aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryaworsky <yaworsky>2005-11-29 13:34:12 +0000
committeryaworsky <yaworsky>2005-11-29 13:34:12 +0000
commit6cbd5fddd7e5be2746d0ceb017aaedd88717848b (patch)
tree0a0367e9c9b998786acdc01a99dd10fb60d0dee0
parent447ff54953c6fd528f161a6d5ab18593db9ad490 (diff)
downloadsyslog-win32-6cbd5fddd7e5be2746d0ceb017aaedd88717848b.tar.gz
syslog-win32-6cbd5fddd7e5be2746d0ceb017aaedd88717848b.tar.xz
syslog-win32-6cbd5fddd7e5be2746d0ceb017aaedd88717848b.zip
Convert all parts of logged message to destination encoding.
This is required if destination encoding is UCS-2 or UCS-4 for example. Otherwise the logfile will not be uniform. Fixed a bug in charset conversion function: divide by zero when cannot convert the first character and calculating new size for the output buffer.
-rw-r--r--daemon/conf.c35
-rw-r--r--daemon/dest_file.c6
-rwxr-xr-xdaemon/dest_relay.c7
-rw-r--r--daemon/syslogd.c53
-rw-r--r--daemon/syslogd.h12
5 files changed, 80 insertions, 33 deletions
diff --git a/daemon/conf.c b/daemon/conf.c
index 78f95c2..9be1c18 100644
--- a/daemon/conf.c
+++ b/daemon/conf.c
@@ -679,11 +679,9 @@ 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?
@@ -693,8 +691,8 @@ static void create_conversion_descriptors( struct logpath* logpath )
if( strcasecmp( source_encoding, destination_encoding ) != 0 )
{
- logpath->message_cd = g_iconv_open( destination_encoding, source_encoding );
- if( logpath->message_cd == (GIConv) -1 )
+ logpath->src2dest_cd = g_iconv_open( destination_encoding, source_encoding );
+ if( logpath->src2dest_cd == (GIConv) -1 )
{
ERR( "Cannot convert messages from %s to %s\n",
source_encoding, destination_encoding );
@@ -706,9 +704,23 @@ static void create_conversion_descriptors( struct logpath* logpath )
source_encoding, destination_encoding );
}
}
+
+ if( strcasecmp( "ASCII", destination_encoding ) != 0 )
+ {
+ logpath->ascii2dest_cd = g_iconv_open( destination_encoding, source_encoding );
+ if( logpath->ascii2dest_cd == (GIConv) -1 )
+ {
+ ERR( "Cannot convert messages from ASCII to %s\n", destination_encoding );
+ }
+ else
+ {
+ TRACE( "Log path %s-%s: converting messages from ASCII to %s\n",
+ logpath->source->name, logpath->destination->name,
+ destination_encoding );
+ }
+ }
}
- /* create charset conversion descriptor for program name */
if( logpath->source->encoding )
{
const gchar *destination_encoding;
@@ -717,15 +729,15 @@ static void create_conversion_descriptors( struct logpath* logpath )
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 )
+ logpath->src2locale_cd = g_iconv_open( destination_encoding, logpath->source->encoding );
+ if( logpath->src2locale_cd == (GIConv) -1 )
{
- ERR( "Cannot convert program names from %s to %s\n",
+ ERR( "Cannot convert locale parts from %s to %s\n",
logpath->source->encoding, destination_encoding );
}
else
{
- TRACE( "Log path %s-%s: converting program name from %s to %s\n",
+ TRACE( "Log path %s-%s: converting locale parts from %s to %s\n",
logpath->source->name, logpath->destination->name,
logpath->source->encoding, destination_encoding );
}
@@ -752,8 +764,9 @@ static void resolve_logpaths()
g_free( logpath );
logpath = g_malloc( sizeof(struct logpath) );
- logpath->message_cd = (GIConv) -1;
- logpath->program_cd = (GIConv) -1;
+ logpath->src2dest_cd = (GIConv) -1;
+ logpath->ascii2dest_cd = (GIConv) -1;
+ logpath->src2locale_cd = (GIConv) -1;
/* find source */
for( item = sources; item; item = item->next )
diff --git a/daemon/dest_file.c b/daemon/dest_file.c
index c4d3cfe..d0b9ccd 100644
--- a/daemon/dest_file.c
+++ b/daemon/dest_file.c
@@ -181,8 +181,8 @@ static void write_message_to_logfile( struct file_writer* writer, struct message
if( INVALID_HANDLE_VALUE == writer->fd )
return;
TRACE_2( "%p: %s\n", writer, (*msg)->message->gstr->str );
- len = string_concat( &buffer, (*msg)->timestamp, space, (*msg)->hostname,
- space, (*msg)->message, line_feed, NULL );
+ len = string_concat( &buffer, (*msg)->timestamp, (*msg)->separator, (*msg)->hostname,
+ (*msg)->separator, (*msg)->message, (*msg)->end_of_line, NULL );
WriteFile( writer->fd, buffer, len, &written, NULL );
g_free( buffer );
release_message( *msg );
@@ -458,7 +458,7 @@ static void make_file_name( char* pattern, struct message* message, char* buffer
case 'f': dest += sprintf( dest, "%d", message->facility ); break;
case 'L': dest += sprintf( dest, "%s", get_priority_name( message->priority ) ); break;
case 'l': dest += sprintf( dest, "%d", message->priority ); break;
- case 'H': dest += sprintf( dest, "%s", message->hostname->gstr->str ); break;
+ case 'H': dest += sprintf( dest, "%s", message->hostname_in_locale->gstr->str ); break;
case 'h': dest += sprintf( dest, "%s", message->sender->gstr->str ); break;
case 'P': dest += sprintf( dest, "%s", message->program->gstr->str ); break;
default: *dest++ = c; break;
diff --git a/daemon/dest_relay.c b/daemon/dest_relay.c
index 0ddf675..701c2c3 100755
--- a/daemon/dest_relay.c
+++ b/daemon/dest_relay.c
@@ -100,10 +100,11 @@ static void put_message_to_relay_dest( struct destination* destination, struct m
pri = string_printf( "<%d>", LOG_MAKEPRI( msg->facility, msg->priority ) );
if( destination->u.relay.omit_hostname )
- len = string_concat( &buffer, pri, msg->timestamp, space, msg->message, line_feed, NULL );
+ len = string_concat( &buffer, pri, msg->timestamp, msg->separator,
+ msg->message, msg->end_of_line, NULL );
else
- len = string_concat( &buffer, pri, msg->timestamp, space,
- msg->hostname, space, msg->message, line_feed, NULL );
+ len = string_concat( &buffer, pri, msg->timestamp, msg->separator, msg->hostname,
+ msg->separator, msg->message, msg->end_of_line, NULL );
string_release( pri );
if( len > 1024 )
diff --git a/daemon/syslogd.c b/daemon/syslogd.c
index 5ff5401..6f981f1 100644
--- a/daemon/syslogd.c
+++ b/daemon/syslogd.c
@@ -83,8 +83,11 @@ struct message* create_message( struct source* source,
g_free( ts );
msg->hostname = string_addref( hostname );
+ msg->hostname_in_locale = string_addref( hostname );
msg->program = string_addref( program );
msg->message = string_addref( message );
+ msg->separator = string_addref( space );
+ msg->end_of_line = string_addref( line_feed );
TRACE_LEAVE( "message=%p\n", msg );
return msg;
@@ -109,8 +112,11 @@ struct message* duplicate_message( struct message* msg )
new_msg->priority = msg->priority;
new_msg->timestamp = string_addref( msg->timestamp );
new_msg->hostname = string_addref( msg->hostname );
+ new_msg->hostname_in_locale = string_addref( msg->hostname_in_locale );
new_msg->program = string_addref( msg->program );
new_msg->message = string_addref( msg->message );
+ new_msg->separator = string_addref( msg->separator );
+ new_msg->end_of_line = string_addref( msg->end_of_line );
TRACE_LEAVE( "new message=%p\n", new_msg );
return new_msg;
@@ -143,8 +149,11 @@ void release_message( struct message* msg )
string_release( msg->sender );
string_release( msg->timestamp );
string_release( msg->hostname );
+ string_release( msg->hostname_in_locale );
string_release( msg->program );
string_release( msg->message );
+ string_release( msg->separator );
+ string_release( msg->end_of_line );
g_free( msg );
TRACE_LEAVE( "done\n" );
}
@@ -223,10 +232,14 @@ static struct string* try_convert_string( struct string* s, GIConv cd )
{
case E2BIG:
/* guess the right output length */
- outbytes = inbytes_left *
- /* average size of destination char: */
- converted_str_len / (s->gstr->len - inbytes_left)
- + 16; /* if the result of above expression too small */
+ if( s->gstr->len > inbytes_left )
+ outbytes = inbytes_left *
+ /* average size of destination char: */
+ converted_str_len / (s->gstr->len - inbytes_left)
+ + 16; /* if the result of above expression too small */
+ else
+ /* cannot convert the first character; choose some initial value */
+ outbytes = 32;
converted_str_allocated += outbytes;
converted_str = g_realloc( converted_str, converted_str_allocated );
outbuf = converted_str + converted_str_len;
@@ -269,7 +282,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;
+ gboolean need_dest_iconv, need_locale_iconv;
struct message *converted_msg;
if( logpath->source != msg->source )
@@ -279,10 +292,10 @@ static void mux_message( struct message* msg )
continue;
/* convert encoding if needed */
- need_message_iconv = logpath->message_cd != (GIConv) -1;
- need_program_iconv = logpath->program_cd != (GIConv) -1;
+ need_dest_iconv = (logpath->src2dest_cd != (GIConv) -1) && (logpath->ascii2dest_cd != (GIConv) -1);
+ need_locale_iconv = logpath->src2locale_cd != (GIConv) -1;
- if( (!need_message_iconv) && (!need_program_iconv) )
+ if( (!need_dest_iconv) && (!need_locale_iconv) )
{
converted_msg = msg;
reference_message( msg );
@@ -291,15 +304,31 @@ static void mux_message( struct message* msg )
{
converted_msg = duplicate_message( msg );
- if( need_message_iconv )
+ if( need_dest_iconv )
{
+ string_release( converted_msg->timestamp );
+ converted_msg->timestamp = try_convert_string( msg->timestamp, logpath->ascii2dest_cd );
+
+ string_release( converted_msg->hostname );
+ converted_msg->hostname = try_convert_string( msg->hostname, logpath->src2dest_cd );
+
string_release( converted_msg->message );
- converted_msg->message = try_convert_string( msg->message, logpath->message_cd );
+ converted_msg->message = try_convert_string( msg->message, logpath->src2dest_cd );
+
+ string_release( converted_msg->separator );
+ converted_msg->separator = try_convert_string( msg->separator, logpath->ascii2dest_cd );
+
+ string_release( converted_msg->end_of_line );
+ converted_msg->end_of_line = try_convert_string( msg->end_of_line, logpath->ascii2dest_cd );
}
- if( need_program_iconv )
+ if( need_locale_iconv )
{
+ string_release( converted_msg->hostname_in_locale );
+ converted_msg->hostname_in_locale = try_convert_string( msg->hostname_in_locale,
+ logpath->src2locale_cd );
+
string_release( converted_msg->program );
- converted_msg->program = try_convert_string( msg->program, logpath->program_cd );
+ converted_msg->program = try_convert_string( msg->program, logpath->src2locale_cd );
}
}
diff --git a/daemon/syslogd.h b/daemon/syslogd.h
index 7b41db8..b7569bb 100644
--- a/daemon/syslogd.h
+++ b/daemon/syslogd.h
@@ -96,9 +96,12 @@ struct message
int facility;
int priority;
struct string *timestamp;
- struct string *hostname;
- struct string *program;
+ struct string *hostname; /* for logging */
+ struct string *hostname_in_locale; /* for filename construction */
+ struct string *program; /* in locale, for filename construction */
struct string *message;
+ struct string *separator;
+ struct string *end_of_line;
};
extern struct message* create_message( struct source* source,
@@ -197,8 +200,9 @@ struct logpath
struct source *source;
struct filter *filter;
struct destination *destination;
- GIConv message_cd; /* charset conversion descriptor for message */
- GIConv program_cd; /* charset conversion descriptor for program name */
+ GIConv src2dest_cd; /* charset conversion descriptor for message */
+ GIConv ascii2dest_cd; /* charset conversion descriptor for ascii parts of message */
+ GIConv src2locale_cd; /* charset conversion descriptor for those parts that are used for filename construction */
};
extern GList *sources;