aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--daemon/Makefile.am4
-rw-r--r--daemon/dest_file.c26
-rwxr-xr-xdaemon/dest_relay.c12
-rw-r--r--daemon/main.c18
-rwxr-xr-xdaemon/string.c116
-rw-r--r--daemon/syslogd.c132
-rw-r--r--daemon/syslogd.h40
7 files changed, 255 insertions, 93 deletions
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 );