aboutsummaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--daemon/Makefile.am2
-rw-r--r--daemon/conf.c85
-rwxr-xr-xdaemon/dest_relay.c195
-rw-r--r--daemon/syslogd.h11
4 files changed, 278 insertions, 15 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 81fddfa..06c1ccc 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -13,7 +13,7 @@ endif
AM_CPPFLAGS += -I. -I../include $(GLIB_CFLAGS)
bin_PROGRAMS = syslogd
-syslogd_SOURCES = conf.c dest_file.c fifo.c listener.c logrotate.c \
+syslogd_SOURCES = conf.c dest_file.c dest_relay.c fifo.c listener.c logrotate.c \
main.c names.c pathnames.c purger.c syslogd.c syslogd.h
syslogd_LDADD = -lws2_32 $(GLIB_LIBS)
diff --git a/daemon/conf.c b/daemon/conf.c
index 9dfb248..c31115b 100644
--- a/daemon/conf.c
+++ b/daemon/conf.c
@@ -125,8 +125,7 @@ static void create_source( int line_number,
/******************************************************************************
* init_file_dest
*
- * read attributes of element, initialize destination structure and append
- * it to the list of destinations
+ * read attributes of element and initialize destination structure
*/
static gboolean init_file_dest( struct destination *dest,
int line_number,
@@ -203,6 +202,46 @@ static gboolean init_file_dest( struct destination *dest,
}
/******************************************************************************
+ * init_relay_dest
+ *
+ * read attributes of element and initialize destination structure
+ */
+static gboolean init_relay_dest( struct destination *dest,
+ int line_number,
+ const gchar** attribute_names,
+ const gchar** attribute_values )
+{
+ const gchar *aname;
+
+ for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ )
+ {
+ const gchar *aval = *attribute_values;
+ if( strcmp( aname, "collector" ) == 0 )
+ dest->u.relay.collector = g_strdup( aval );
+ else if( strcmp( aname, "omit_hostname" ) == 0 )
+ {
+ if( strcmp( aval, "yes" ) == 0 )
+ dest->u.relay.omit_hostname = TRUE;
+ else if( strcmp( aval, "no" ) == 0 )
+ dest->u.relay.omit_hostname = FALSE;
+ else
+ {
+ dest->u.relay.omit_hostname = FALSE;
+ ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d; assumed \"no\"\n",
+ aval, aname, line_number );
+ }
+ }
+ }
+ if( !dest->u.relay.collector )
+ {
+ ERR( "Undefined destination relay at line %d\n", line_number );
+ return FALSE;
+ }
+
+ return init_destination_relay( dest );
+}
+
+/******************************************************************************
* create_destination
*
* read attributes of element, initialize destination structure and append
@@ -231,6 +270,11 @@ static void create_destination( int line_number,
dest->type = DT_FILE;
break;
}
+ else if( strcmp( aname, "collector" ) == 0 )
+ {
+ dest->type = DT_RELAY;
+ break;
+ }
}
if( !dest->name )
{
@@ -245,6 +289,10 @@ static void create_destination( int line_number,
r = init_file_dest( dest, line_number, attribute_names, attribute_values );
break;
+ case DT_RELAY:
+ r = init_relay_dest( dest, line_number, attribute_names, attribute_values );
+ break;
+
default:
ERR( "Undefined destination type at line %d\n", line_number );
break;
@@ -734,17 +782,28 @@ static void dump_configuration()
for( item = destinations; item; item = item->next )
{
struct destination *d = item->data;
- TRACE( "\tname=%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->u.file.rotate == RP_DAILY)? "daily"
- : (d->u.file.rotate == RP_WEEKLY)? "weekly"
- : (d->u.file.rotate == RP_MONTHLY)? "monthly"
- : "undefined",
- d->u.file.size, d->u.file.backlogs, d->u.file.ifempty? "yes" : "no",
- d->u.file.olddir? d->u.file.olddir : "NULL",
- d->u.file.compresscmd? d->u.file.compresscmd : "NULL" );
+ switch( d->type )
+ {
+ case DT_FILE:
+ TRACE( "\tname=%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->u.file.rotate == RP_DAILY)? "daily"
+ : (d->u.file.rotate == RP_WEEKLY)? "weekly"
+ : (d->u.file.rotate == RP_MONTHLY)? "monthly"
+ : "undefined",
+ d->u.file.size, d->u.file.backlogs, d->u.file.ifempty? "yes" : "no",
+ d->u.file.olddir? d->u.file.olddir : "NULL",
+ d->u.file.compresscmd? d->u.file.compresscmd : "NULL" );
+ break;
+ case DT_RELAY:
+ TRACE( "\tname=%s\tcollector=%s\n"
+ "\t\tomit_hostname=%s\n",
+ d->name, d->u.file.name_pattern,
+ d->u.relay.omit_hostname? "yes" : "no" );
+ break;
+ }
}
TRACE( "Filters:\n" );
for( item = filters; item; item = item->next )
diff --git a/daemon/dest_relay.c b/daemon/dest_relay.c
new file mode 100755
index 0000000..4bea0c6
--- /dev/null
+++ b/daemon/dest_relay.c
@@ -0,0 +1,195 @@
+/*
+ * dest_relay.c - syslogd implementation for windows, relay destination
+ *
+ * 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 <winsock2.h>
+
+#include <glib.h>
+
+#include <syslog.h>
+#include <syslogd.h>
+
+struct dest_extra
+{
+ SOCKADDR_IN addr;
+ SOCKET sock;
+};
+
+/******************************************************************************
+ * resolve_address
+ *
+ * Parse 'collector' parameter and init 'addr' in the dest_extra.
+ * Collector should contain host name or address optionally followed by colon
+ * and port number.
+ */
+static gboolean resolve_addr( struct destination* destination )
+{
+ struct dest_extra *extra = destination->extra;
+ gboolean ret = FALSE;
+ char *p;
+ gchar *host;
+ struct hostent *phe;
+
+ TRACE_ENTER( "destination=%s, collector=%s\n",
+ destination->name, destination->u.relay.collector );
+
+ memset( &extra->addr, 0, sizeof(SOCKADDR_IN) );
+ extra->addr.sin_family = AF_INET;
+
+ p = strchr( destination->u.relay.collector, ':' );
+ if( p )
+ host = g_strndup( destination->u.relay.collector,
+ p - destination->u.relay.collector );
+ else
+ host = g_strdup( destination->u.relay.collector );
+
+ phe = gethostbyname( host );
+ if( !phe )
+ {
+ ERR( "Cannot resolve hostname %s for destination %s\n",
+ destination->u.relay.collector, destination->name );
+ goto done;
+ }
+
+ memcpy( &extra->addr.sin_addr.s_addr, phe->h_addr, phe->h_length );
+
+ if( p )
+ extra->addr.sin_port = htons( (unsigned short) strtoul( p + 1, NULL, 0 ) );
+ else
+ extra->addr.sin_port = htons( SYSLOG_PORT );
+
+ TRACE( "collector=%d.%d.%d.%d:%d\n",
+ extra->addr.sin_addr.S_un.S_un_b.s_b1, extra->addr.sin_addr.S_un.S_un_b.s_b2,
+ extra->addr.sin_addr.S_un.S_un_b.s_b3, extra->addr.sin_addr.S_un.S_un_b.s_b4,
+ ntohs( extra->addr.sin_port ) );
+
+ ret = TRUE;
+
+done:
+ g_free( host );
+
+ TRACE_LEAVE( "done; ret=%d\n", ret );
+ return ret;
+}
+
+/******************************************************************************
+ * put_message_to_relay_dest
+ */
+static void put_message_to_relay_dest( struct destination* destination, struct message* msg )
+{
+ struct dest_extra *extra = destination->extra;
+ char pri[16];
+ gchar *buffer;
+ int len;
+
+ TRACE_ENTER( "msg=%p, destination=%s\n", msg, destination->name );
+
+ sprintf( pri, "<%d>", LOG_MAKEPRI( msg->facility, msg->priority ) );
+ if( destination->u.relay.omit_hostname )
+ buffer = g_strconcat( pri, msg->timestamp, " ", msg->message, "\n", NULL );
+ else
+ buffer = g_strconcat( pri, msg->timestamp, " ",
+ msg->hostname, " ", msg->message, "\n", NULL );
+
+ len = strlen( buffer );
+ if( len > 1024 )
+ {
+ buffer[ 1023 ] = '\n';
+ buffer[ 1024 ] = '\0';
+ len = 1024;
+ }
+ if( sendto( extra->sock, buffer, len, 0,
+ (SOCKADDR*) &extra->addr, sizeof(SOCKADDR_IN) ) == SOCKET_ERROR )
+ ERR( "sendto error %lu\n", WSAGetLastError() );
+
+ g_free( buffer );
+
+ TRACE_LEAVE( "done\n" );
+}
+
+/******************************************************************************
+ * finalize_relay_dest
+ *
+ * close socket
+ */
+static void finalize_relay_dest( struct destination* destination )
+{
+ struct dest_extra *extra = destination->extra;
+
+ TRACE_ENTER( "destination=%s\n", destination->name );
+ if( extra->sock != INVALID_SOCKET )
+ {
+ closesocket( extra->sock );
+ }
+ TRACE_LEAVE( "done\n" );
+}
+
+/******************************************************************************
+ * init_destination_relay
+ *
+ * initialize relay destination: resolve address of collector and create socket
+ */
+gboolean init_destination_relay( struct destination* destination )
+{
+ struct dest_extra *extra;
+ int n;
+
+ TRACE_ENTER( "destination=%s\n", destination->name );
+
+ extra = g_malloc( sizeof(struct dest_extra) );
+ destination->extra = extra;
+ destination->put = put_message_to_relay_dest;
+ destination->fini = finalize_relay_dest;
+ extra->sock = INVALID_SOCKET;
+
+ if( !resolve_addr( destination ) )
+ goto error;
+
+ for( n = 0;; n++ )
+ {
+ SOCKADDR_IN sa_local;
+
+ extra->sock = socket( AF_INET, SOCK_DGRAM, 0 );
+ if( INVALID_SOCKET == extra->sock )
+ {
+ ERR( "Cannot create socket\n" );
+ goto error;
+ }
+
+ memset( &sa_local, 0, sizeof(SOCKADDR_IN) );
+ sa_local.sin_family = AF_INET;
+ if( bind( extra->sock, (SOCKADDR*) &sa_local, sizeof(SOCKADDR_IN) ) == 0 )
+ break;
+ closesocket( extra->sock );
+ extra->sock = INVALID_SOCKET;
+ if( n == 100 )
+ {
+ ERR( "Cannot bind socket\n" );
+ goto error;
+ }
+ Sleep(0);
+ }
+ TRACE_LEAVE( "ok\n" );
+ return TRUE;
+
+error:
+ if( extra->sock != INVALID_SOCKET )
+ closesocket( extra->sock );
+ g_free( destination->extra );
+ TRACE_LEAVE( "error\n" );
+ return FALSE;
+}
diff --git a/daemon/syslogd.h b/daemon/syslogd.h
index 8919ede..20dfa00 100644
--- a/daemon/syslogd.h
+++ b/daemon/syslogd.h
@@ -106,7 +106,8 @@ struct source
enum destination_type
{
DT_UNDEFINED,
- DT_FILE
+ DT_FILE,
+ DT_RELAY
};
enum rotation_period
@@ -130,6 +131,12 @@ struct destination_file
gchar *compressoptions;
};
+struct destination_relay
+{
+ gchar *collector;
+ gboolean omit_hostname;
+};
+
struct destination;
typedef void (*dest_put)( struct destination* destination, struct message* message );
@@ -142,6 +149,7 @@ struct destination
union
{
struct destination_file file;
+ struct destination_relay relay;
} u;
void *extra;
/* methods */
@@ -171,6 +179,7 @@ extern GList *logpaths;
extern gboolean read_configuration();
extern gboolean init_destination_file( struct destination* destination );
+extern gboolean init_destination_relay( struct destination* destination );
/* queue */
struct fifo_item