From a704fc5981f7f2c0a3179f62f0ce818f75467078 Mon Sep 17 00:00:00 2001
From: yaworsky <yaworsky>
Date: Tue, 15 Nov 2005 11:59:52 +0000
Subject: Replaced 0-terminated strings with reference counted ones

---
 daemon/Makefile.am  |   4 +-
 daemon/dest_file.c  |  26 +++++++----
 daemon/dest_relay.c |  12 ++---
 daemon/main.c       |  18 +++++--
 daemon/string.c     | 116 +++++++++++++++++++++++++++++++++++++++++++++
 daemon/syslogd.c    | 132 ++++++++++++++++++++++++++++------------------------
 daemon/syslogd.h    |  40 ++++++++++++----
 7 files changed, 255 insertions(+), 93 deletions(-)
 create mode 100755 daemon/string.c

(limited to 'daemon')

diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 5e2a426..bda0ed4 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -14,8 +14,8 @@ AM_CPPFLAGS += -I. -I../include $(GLIB_CFLAGS)
 
 bin_PROGRAMS = syslogd
 syslogd_SOURCES = conf.c dest_file.c dest_relay.c fifo.c logrotate.c \
-                  main.c names.c pathnames.c purger.c syslogd.c syslogd.h \
-                  udp_listener.c
+                  main.c names.c pathnames.c purger.c string.c syslogd.c \
+                  syslogd.h udp_listener.c
 syslogd_LDADD = -lws2_32 $(GLIB_LIBS)
 
 endif
diff --git a/daemon/dest_file.c b/daemon/dest_file.c
index ef28062..f08cedb 100644
--- a/daemon/dest_file.c
+++ b/daemon/dest_file.c
@@ -67,8 +67,10 @@ static gboolean compare_current_and_first_messages( struct file_writer* writer )
 {
     TRACE_ENTER( "%p\n", writer );
 
-    if( strcmp( writer->current_msg->hostname, writer->first_msg->hostname )
-        || strcmp( writer->current_msg->message, writer->first_msg->message ) )
+    if( string_compare( writer->current_msg->hostname,
+                        writer->first_msg->hostname )
+        || string_compare( writer->current_msg->message,
+                           writer->first_msg->message ) )
     {
         release_message( writer->first_msg );
         writer->first_msg = NULL;
@@ -173,13 +175,15 @@ check_hold_time:
 static void write_message_to_logfile( struct file_writer* writer, struct message** msg )
 {
     gchar *buffer;
+    gsize len;
     DWORD written;
 
     if( INVALID_HANDLE_VALUE == writer->fd )
         return;
-    TRACE_2( "%p: %s\n", writer, (*msg)->message );
-    buffer = g_strconcat( (*msg)->timestamp, " ", (*msg)->hostname, " ", (*msg)->message, "\n", NULL );
-    WriteFile( writer->fd, buffer, strlen( buffer ), &written, NULL );
+    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 );
+    WriteFile( writer->fd, buffer, len, &written, NULL );
     g_free( buffer );
     release_message( *msg );
     *msg = NULL;
@@ -209,7 +213,7 @@ static void flush_coalescer( struct file_writer* writer )
         size = snprintf( buffer, sizeof(buffer),
                          "%s %2d %02d:%02d:%02d %s syslog: last message repeated %d times\n",
                          str_month[ stm.wMonth - 1 ], stm.wDay, stm.wHour, stm.wMinute, stm.wSecond,
-                         local_hostname,
+                         local_hostname->gstr->str,
                          writer->coalesce_count - 1 );
         WriteFile( writer->fd, buffer, size, &written, NULL );
         TRACE_2( "%p made informational message\n", writer );
@@ -463,9 +467,9 @@ 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 ); break;
-        case 'h': dest += sprintf( dest, "%s", message->sender ); break;
-        case 'P': dest += sprintf( dest, "%s", message->program ); break;
+        case 'H': dest += sprintf( dest, "%s", message->hostname->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;
         }
     }
@@ -485,7 +489,9 @@ static void put_message_to_file_dest( struct destination* destination, struct me
     TRACE_ENTER( "msg=%p, destination=%s\n", msg, destination->name );
     make_file_name( destination->u.file.name_pattern, msg, file_name );
     EnterCriticalSection( &extra->cs_file_writers );
-    /* find existing writer */
+    /* find existing writer
+       FIXME: could we do this better?
+     */
     for( writer = NULL, item = extra->file_writers; item; item = item->next )
     {
         struct file_writer *w = item->data;
diff --git a/daemon/dest_relay.c b/daemon/dest_relay.c
index 4bea0c6..0ddf675 100755
--- a/daemon/dest_relay.c
+++ b/daemon/dest_relay.c
@@ -92,20 +92,20 @@ done:
 static void put_message_to_relay_dest( struct destination* destination, struct message* msg )
 {
     struct dest_extra *extra = destination->extra;
-    char pri[16];
+    struct string *pri;
     gchar *buffer;
     int len;
 
     TRACE_ENTER( "msg=%p, destination=%s\n", msg, destination->name );
 
-    sprintf( pri, "<%d>", LOG_MAKEPRI( msg->facility, msg->priority ) );
+    pri = string_printf( "<%d>", LOG_MAKEPRI( msg->facility, msg->priority ) );
     if( destination->u.relay.omit_hostname )
-        buffer = g_strconcat( pri, msg->timestamp, " ", msg->message, "\n", NULL );
+        len = string_concat( &buffer, pri, msg->timestamp, space, msg->message, line_feed, NULL );
     else
-        buffer = g_strconcat( pri, msg->timestamp, " ",
-                              msg->hostname, " ", msg->message, "\n", NULL );
+        len = string_concat( &buffer, pri, msg->timestamp, space,
+                             msg->hostname, space, msg->message, line_feed, NULL );
+    string_release( pri );
 
-    len = strlen( buffer );
     if( len > 1024 )
     {
         buffer[ 1023 ] = '\n';
diff --git a/daemon/main.c b/daemon/main.c
index 91e9087..ee91238 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -28,7 +28,10 @@
 
 HANDLE service_stop_event;
 
-char local_hostname[ MAX_COMPUTERNAME_LENGTH + 1 ];
+struct string *local_hostname;
+struct string *self_program_name;
+struct string *space;
+struct string *line_feed;
 
 int verbosity_level = 0;
 
@@ -468,10 +471,15 @@ int main( int argc, char* argv[] )
     char *priority = NULL;
     int getopt_failure = 0;
     WSADATA wsd;
+    char name_buf[ MAX_COMPUTERNAME_LENGTH + 1 ];
     DWORD size;
 
     SetUnhandledExceptionFilter( exception_handler );
 
+    self_program_name = string_new( "syslog" );
+    space = string_new( " " );
+    line_feed = string_new( "\n" );
+
     if( WSAStartup( MAKEWORD( 2, 2 ), &wsd ) )
     {
         ERR( "Cannot initialize winsock; error %lu\n", WSAGetLastError() );
@@ -479,13 +487,13 @@ int main( int argc, char* argv[] )
     }
 
     /* get local host name */
-    size = sizeof(local_hostname);
-    if( !GetComputerName( local_hostname, &size ) )
+    size = sizeof(name_buf);
+    if( !GetComputerName( name_buf, &size ) )
     {
         ERR( "Cannot get computer name; error %lu\n", GetLastError() );
         return 1;
     }
-    TRACE( "local host name=%s\n", local_hostname );
+    local_hostname = string_new_len( name_buf, size );
 
     /* get windows version */
     vi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
@@ -581,6 +589,8 @@ int main( int argc, char* argv[] )
     if( getopt_failure )
         return 1;
 
+    TRACE( "local host name=%s\n", local_hostname->gstr->str );
+
     /* handle flags in order of priority */
     /* at first, check instance name */
     if( instance_name )
diff --git a/daemon/string.c b/daemon/string.c
new file mode 100755
index 0000000..6684664
--- /dev/null
+++ b/daemon/string.c
@@ -0,0 +1,116 @@
+/*
+ * string.c - syslogd implementation for windows, reference counted strings
+ *
+ * Created by Alexander Yaworsky
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <windows.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+
+#include <syslog.h>
+#include <syslogd.h>
+
+struct string* string_new( const gchar* init )
+{
+    struct string *s = g_malloc( sizeof(struct string) );
+    s->refcount = 1;
+    s->gstr = g_string_new( init );
+    return s;
+}
+
+struct string* string_new_len( const gchar* init, gssize len )
+{
+    struct string *s = g_malloc( sizeof(struct string) );
+    s->refcount = 1;
+    s->gstr = g_string_new_len( init, len );
+    return s;
+}
+
+struct string* string_addref( struct string* s )
+{
+    InterlockedIncrement( &s->refcount );
+    return s;
+}
+
+void string_release( struct string* s )
+{
+    if( InterlockedDecrement( &s->refcount ) )
+        return;
+
+    g_string_free( s->gstr, TRUE );
+    g_free( s );
+}
+
+gsize string_concat( gchar** result, struct string* s, ... )
+{
+    va_list args;
+    struct string *str;
+    gsize length = s->gstr->len;
+    gchar *p;
+
+    va_start( args, s );
+    while( (str = va_arg( args, struct string* )) )
+        length += str->gstr->len;
+    va_end( args );
+
+    *result = g_malloc( length + 1 );
+
+    memcpy( *result, s->gstr->str, s->gstr->len );
+    p = *result + s->gstr->len;
+
+    va_start( args, s );
+    while( (str = va_arg( args, struct string* )) )
+    {
+        memcpy( p, str->gstr->str, str->gstr->len );
+        p += str->gstr->len;
+    }
+    *p = 0;
+    va_end( args );
+
+    return length;
+}
+
+struct string* string_vprintf( gchar* fmt, va_list args )
+{
+    struct string *s;
+    gchar *buf;
+    int len;
+
+    len = g_vasprintf( &buf, fmt, args );
+    s = string_new_len( buf, len );
+    g_free( buf );
+    return s;
+}
+
+struct string* string_printf( gchar* fmt, ... )
+{
+    struct string *s;
+    va_list args;
+
+    va_start( args, fmt );
+    s = string_vprintf( fmt, args );
+    va_end( args );
+    return s;
+}
+
+int string_compare( struct string* s1, struct string* s2 )
+{
+    if( s1 == s2 )
+        return 0;
+    return strcmp( s1->gstr->str, s2->gstr->str );
+}
diff --git a/daemon/syslogd.c b/daemon/syslogd.c
index dc947b3..da53e60 100644
--- a/daemon/syslogd.c
+++ b/daemon/syslogd.c
@@ -38,7 +38,7 @@ static struct source** internal_source_references = NULL;
 struct hostname
 {
     struct sockaddr_in addr;
-    gchar *host;
+    struct string *host;
     time_t top_age;  /* zero prevents aging */
 };
 static GList *hostnames = NULL;
@@ -55,35 +55,37 @@ char *str_month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  * create_message
  *
  * Create a new message with refcount=1.
- * The caller should allocate sender, hostname, program and message strings.
- * The function simply copies these pointers to the structure and the caller
- * should not free allocated strings.
  */
 struct message* create_message( struct source* source,
-                                gchar* sender,
+                                struct string* sender,
                                 int facility, int priority,
                                 LPSYSTEMTIME timestamp,
-                                gchar* hostname,
-                                gchar* program,
-                                gchar* message )
+                                struct string* hostname,
+                                struct string* program,
+                                struct string* message )
 {
     struct message *msg;
+    gchar *ts;
 
     TRACE_ENTER( "\n" );
 
     msg = g_malloc( sizeof(struct message) );
     msg->refcount = 1;
     msg->source = source;
-    msg->sender = sender;
+    msg->sender = string_addref( sender );
     msg->facility = facility;
     msg->priority = priority;
-    msg->timestamp = g_strdup_printf( "%s %2d %02d:%02d:%02d",
-                                      str_month[ timestamp->wMonth - 1 ],
-                                      timestamp->wDay, timestamp->wHour,
-                                      timestamp->wMinute, timestamp->wSecond );
-    msg->hostname = hostname;
-    msg->program = program;
-    msg->message = message;
+
+    ts = g_strdup_printf( "%s %2d %02d:%02d:%02d",
+                          str_month[ timestamp->wMonth - 1 ],
+                          timestamp->wDay, timestamp->wHour,
+                          timestamp->wMinute, timestamp->wSecond );
+    msg->timestamp = string_new( ts );
+    g_free( ts );
+
+    msg->hostname = string_addref( hostname );
+    msg->program = string_addref( program );
+    msg->message = string_addref( message );
 
     TRACE_LEAVE( "message=%p\n", msg );
     return msg;
@@ -101,15 +103,15 @@ struct message* duplicate_message( struct message* msg )
     TRACE_ENTER( "message=%p\n", msg );
 
     new_msg = g_malloc( sizeof(struct message) );
-    new_msg->refcount = 1;
-    new_msg->source = msg->source;
-    new_msg->sender = g_strdup( msg->sender );
-    new_msg->facility = msg->facility;
-    new_msg->priority = msg->priority;
-    new_msg->timestamp = g_strdup( msg->timestamp );
-    new_msg->hostname = g_strdup( msg->hostname );
-    new_msg->program = g_strdup( msg->program );
-    new_msg->message = g_strdup( msg->message );
+    new_msg->refcount  = 1;
+    new_msg->source    = msg->source;
+    new_msg->sender    = string_addref( msg->sender );
+    new_msg->facility  = msg->facility;
+    new_msg->priority  = msg->priority;
+    new_msg->timestamp = string_addref( msg->timestamp );
+    new_msg->hostname  = string_addref( msg->hostname );
+    new_msg->program   = string_addref( msg->program );
+    new_msg->message   = string_addref( msg->message );
 
     TRACE_LEAVE( "new message=%p\n", new_msg );
     return new_msg;
@@ -139,11 +141,11 @@ void release_message( struct message* msg )
         TRACE_LEAVE( "done; still referenced\n" );
         return;
     }
-    g_free( msg->sender );
-    g_free( msg->timestamp );
-    g_free( msg->hostname );
-    g_free( msg->program );
-    g_free( msg->message );
+    string_release( msg->sender );
+    string_release( msg->timestamp );
+    string_release( msg->hostname );
+    string_release( msg->program );
+    string_release( msg->message );
     g_free( msg );
     TRACE_LEAVE( "done\n" );
 }
@@ -163,7 +165,7 @@ static void convert_message_encoding( struct message* msg )
         return;
     }
 
-    converted_msg = g_convert_with_iconv( msg->message, -1,
+    converted_msg = g_convert_with_iconv( msg->message->gstr->str, -1,
                                           conversion_descriptor, NULL, NULL, NULL );
     if( !converted_msg )
     {
@@ -171,10 +173,11 @@ static void convert_message_encoding( struct message* msg )
         return;
     }
 
-    g_free( msg->message );
-    msg->message = converted_msg;
+    string_release( msg->message );
+    msg->message = string_new( converted_msg );
+    g_free( converted_msg );
 
-    TRACE_LEAVE( "done; %s\n", msg->message );
+    TRACE_LEAVE( "done; %s\n", msg->message->gstr->str );
 }
 
 /******************************************************************************
@@ -243,14 +246,16 @@ static void mux_message( struct message* msg )
 /******************************************************************************
  * get_hostname
  *
- * convert addr to string and return it
+ * convert addr to string and return it;
+ * string should be released after use
  */
-static gchar* get_hostname( struct sockaddr_in* addr )
+static struct string* get_hostname( struct sockaddr_in* addr )
 {
-    gchar *ret;
+    struct string *ret;
     time_t current_time;
     GList *item;
     struct hostname *new_hostname;
+    char buf[16];
 
     TRACE_ENTER( "%d.%d.%d.%d\n",
                  addr->sin_addr.S_un.S_un_b.s_b1, addr->sin_addr.S_un.S_un_b.s_b2,
@@ -268,7 +273,7 @@ static gchar* get_hostname( struct sockaddr_in* addr )
             GList *next_item = item->next;
 
             TRACE_2( "delete old entry %s\n", h->host );
-            g_free( h->host );
+            string_release( h->host );
             g_free( h );
             hostnames = g_list_delete_link( hostnames, item );
             item = next_item;
@@ -277,7 +282,7 @@ static gchar* get_hostname( struct sockaddr_in* addr )
         if( h->addr.sin_addr.S_un.S_addr == addr->sin_addr.S_un.S_addr )
         {
             /* found in cache */
-            ret = g_strdup( h->host );
+            ret = string_addref( h->host );
             /* move entry to the beginning of the list */
             item->data = hostnames->data;
             hostnames->data = h;
@@ -296,19 +301,19 @@ static gchar* get_hostname( struct sockaddr_in* addr )
         new_hostname->top_age = time(NULL) + HOSTNAME_LIFETIME;
         if( !he )
             goto use_addr;
-        new_hostname->host = g_strdup( he->h_name );
+        new_hostname->host = string_new( he->h_name );
     }
     else
     {
         new_hostname->top_age = 0;
 use_addr:
-        new_hostname->host = g_malloc( 16 );
-        sprintf( new_hostname->host, "%d.%d.%d.%d",
+        sprintf( buf, "%d.%d.%d.%d",
                  addr->sin_addr.S_un.S_un_b.s_b1, addr->sin_addr.S_un.S_un_b.s_b2,
                  addr->sin_addr.S_un.S_un_b.s_b3, addr->sin_addr.S_un.S_un_b.s_b4 );
+        new_hostname->host = string_new( buf );
     }
     hostnames = g_list_prepend( hostnames, new_hostname );
-    ret = g_strdup( new_hostname->host );
+    ret = string_addref( new_hostname->host );
     TRACE_LEAVE( "done; ret=%s\n", ret );
     return ret;
 }
@@ -322,7 +327,7 @@ static void free_hostnames()
     for( item = hostnames; item; item = item->next )
     {
         struct hostname *h = item->data;
-        g_free( h->host );
+        string_release( h->host );
         g_free( h );
     }
     g_list_free( hostnames );
@@ -455,7 +460,7 @@ done:
 static struct message* parse_raw_message( struct raw_message* raw_msg )
 {
     gchar *current_part, *next_part;
-    gchar *sender, *hostname, *program, *message;
+    struct string *sender, *hostname, *program, *message;
     int facility, priority;
     SYSTEMTIME timestamp;
     struct message *msg;
@@ -474,8 +479,8 @@ static struct message* parse_raw_message( struct raw_message* raw_msg )
     {
         /* no valid timestamp */
         TRACE_2( "no valid timestamp: msg=%s\n", current_part );
-        hostname = g_strdup( sender );
-        message = g_strdup( current_part );
+        hostname = string_addref( sender );
+        message = string_new( current_part );
     }
     else
     {
@@ -486,33 +491,38 @@ static struct message* parse_raw_message( struct raw_message* raw_msg )
         if( *next_part != ' ' )
         {
             /* invalid hostname */
-            hostname = g_strdup( sender );
-            message = g_strdup( current_part );
-            TRACE_2( "invalid hostname; set sender (%s); msg=%s\n", hostname, message );
+            hostname = string_addref( sender );
+            message = string_new( current_part );
+            TRACE_2( "invalid hostname; set sender (%s); msg=%s\n",
+                     hostname->gstr->str, message->gstr->str );
         }
         else
         {
-            hostname = g_strndup( current_part, next_part - current_part );
+            hostname = string_new_len( current_part, next_part - current_part );
             while( *next_part == ' ' && *next_part != 0 )
                 next_part++;
-            message = g_strdup( next_part );
-            TRACE_2( "hostname=%s; msg=%s\n", hostname, message );
+            message = string_new( next_part );
+            TRACE_2( "hostname=%s; msg=%s\n", hostname->gstr->str, message->gstr->str );
         }
     }
 
     /* try to find program name */
-    current_part = message;
+    current_part = message->gstr->str;
     next_part = current_part;
     while( *next_part != ' ' && *next_part != ':' && *next_part != '[' && *next_part != 0 )
         next_part++;
     if( *next_part == ' ' || *next_part == 0 )
-        program = g_strdup("");
+        program = string_new("");
     else
-        program = g_strndup( current_part, next_part - current_part );
+        program = string_new_len( current_part, next_part - current_part );
 
     /* create message */
     msg = create_message( raw_msg->source, sender, facility, priority,
                           &timestamp, hostname, program, message );
+    string_release( sender );
+    string_release( hostname );
+    string_release( program );
+    string_release( message );
 
     /* destroy raw message */
     g_free( raw_msg->msg );
@@ -551,7 +561,7 @@ unsigned number_of_sources( enum source_type type )
  */
 void log_internal( int pri, char* fmt, ... )
 {
-    gchar *sender, *hostname, *program, *msg;
+    struct string *sender, *hostname, *program, *msg;
     va_list args;
     SYSTEMTIME stm;
     int i;
@@ -562,12 +572,12 @@ void log_internal( int pri, char* fmt, ... )
     if( 0 == internal_source_count )
         goto done;
 
-    sender = g_strdup( local_hostname );
-    hostname = g_strdup( local_hostname );
-    program = g_strdup( "syslog" );
+    sender = string_addref( local_hostname );
+    hostname = string_addref( local_hostname );
+    program = string_addref( self_program_name );
 
     va_start( args, fmt );
-    msg = g_strdup_vprintf( fmt, args );
+    msg = string_vprintf( fmt, args );
     va_end( args );
 
     GetLocalTime( &stm );
diff --git a/daemon/syslogd.h b/daemon/syslogd.h
index 0bcd1fb..c48f8f8 100644
--- a/daemon/syslogd.h
+++ b/daemon/syslogd.h
@@ -34,9 +34,29 @@ extern void display_message( FILE* fd, char* file, int line, const char* func, c
 #define TRACE_LEAVE TRACE_2
 #define ERR( fmt... ) display_message( stderr, __FILE__, __LINE__, __FUNCTION__, fmt )
 
+/* refcounted string */
+struct string
+{
+    LONG refcount;
+    GString *gstr;
+};
+
+extern struct string* string_new( const gchar* init );
+extern struct string* string_new_len( const gchar* init, gssize len );
+extern struct string* string_addref( struct string* s );
+extern void string_release( struct string* s );
+extern struct string* string_vprintf( gchar* fmt, va_list args );
+extern struct string* string_printf( gchar* fmt, ... );
+extern gsize string_concat( gchar** result, struct string* s, ... );
+extern int string_compare( struct string* s1, struct string* s2 );
+
+/* misc global stuff */
 extern HANDLE service_stop_event;
 
-extern char local_hostname[];
+extern struct string *local_hostname;
+extern struct string *self_program_name;
+extern struct string *space;
+extern struct string *line_feed;
 
 extern char *str_month[];
 
@@ -74,22 +94,22 @@ struct message
 {
     LONG refcount;
     struct source *source;
-    gchar *sender;
+    struct string *sender;
     int facility;
     int priority;
-    gchar *timestamp;
-    gchar *hostname;
-    gchar *program;
-    gchar *message;
+    struct string *timestamp;
+    struct string *hostname;
+    struct string *program;
+    struct string *message;
 };
 
 extern struct message* create_message( struct source* source,
-                                       gchar* sender,
+                                       struct string* sender,
                                        int facility, int priority,
                                        LPSYSTEMTIME timestamp,
-                                       gchar* hostname,
-                                       gchar* program,
-                                       gchar* message );
+                                       struct string* hostname,
+                                       struct string* program,
+                                       struct string* message );
 extern struct message* duplicate_message( struct message* msg );
 extern void reference_message( struct message* msg );
 extern void release_message( struct message* msg );
-- 
cgit v1.2.3