diff options
-rw-r--r-- | daemon/conf.c | 635 |
1 files changed, 371 insertions, 264 deletions
diff --git a/daemon/conf.c b/daemon/conf.c index 19a5ad2..0166712 100644 --- a/daemon/conf.c +++ b/daemon/conf.c @@ -65,333 +65,440 @@ static gboolean prolog_expected = TRUE; static struct filter *current_filter = NULL; /****************************************************************************** - * xml_start_element + * create_source * - * parse configuration elements + * read attributes of element, initialize source structure and append + * it to the list of sources */ -static void xml_start_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) +static void create_source( int line_number, + const gchar** attribute_names, + const gchar** attribute_values ) { - const gchar *aname, *aval; - int line_number; + const gchar *aname; + struct source *source = g_malloc( sizeof(struct source) ); - prolog_expected = FALSE; + source->name = NULL; + source->type = ST_UNDEFINED; + memset( &source->udp, 0, sizeof(source->udp) ); + source->udp.sin_family = AF_INET; + source->udp.sin_port = htons( SYSLOG_PORT ); - g_markup_parse_context_get_position( context, &line_number, NULL ); + for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) + { + const gchar *aval = *attribute_values; + if( strcmp( aname, "name" ) == 0 ) + source->name = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + else if( strcmp( aname, "type" ) == 0 ) + { + if( strcmp( aval, "internal" ) == 0 ) + source->type = ST_INTERNAL; + else if( strcmp( aval, "udp" ) == 0 ) + source->type = ST_UDP; + } + else if( strcmp( aname, "interface" ) == 0 ) + { + struct hostent *he = gethostbyname( aval ); + if( !he ) + { + ERR( "Cannot resolve hostname %s; error %lu\n", aval, WSAGetLastError() ); + g_free( source ); + return; + } + memcpy( &source->udp.sin_addr.s_addr, he->h_addr, he->h_length ); + } + else if( strcmp( aname, "port" ) == 0 ) + source->udp.sin_port = htons( strtoul( aval, NULL, 0 ) ); + } - /* top-level elements */ - if( strcmp( element_name, "source" ) == 0 ) + if( !source->name ) + ERR( "Undefined source name at line %d\n", line_number ); + if( ST_UNDEFINED == source->type ) + ERR( "Undefined source type at line %d\n", line_number ); + if( (!source->name) || ST_UNDEFINED == source->type ) + { + g_free( source ); + return; + } + sources = g_list_append( sources, source ); +} + +/****************************************************************************** + * create_destination + * + * read attributes of element, initialize destination structure and append + * it to the list of destinations + */ +static void create_destination( int line_number, + const gchar** attribute_names, + const gchar** attribute_values ) +{ + const gchar *aname; + struct destination *dest = g_malloc0( sizeof(struct destination) ); + + /* at first, we must determine de*/ + for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) { - struct source *source = g_malloc( sizeof(struct source) ); + const gchar *aval = *attribute_values; + if( strcmp( aname, "name" ) == 0 ) + dest->name = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + else if( strcmp( aname, "file" ) == 0 ) + dest->file = normalize_pathname( aval ); + else if( strcmp( aname, "rotate" ) == 0 ) + { + if( strcmp( aval, "daily" ) == 0 ) + dest->rotate = RP_DAILY; + else if( strcmp( aval, "weekly" ) == 0 ) + dest->rotate = RP_WEEKLY; + else if( strcmp( aval, "monthly" ) == 0 ) + dest->rotate = RP_MONTHLY; + else + { + ERR( "Invalid rotation period at line %d\n", line_number ); + dest->rotate = RP_INVALID; + } + } + else if( strcmp( aname, "size" ) == 0 ) + { + char *endptr; + dest->size = strtoul( aval, &endptr, 0 ); + if( 'k' == *endptr ) + dest->size *= 1024; + else if( 'M' == *endptr ) + dest->size *= 1024 * 1024; + } + else if( strcmp( aname, "backlogs" ) == 0 ) + dest->backlogs = strtoul( aval, NULL, 0 ); + else if( strcmp( aname, "ifempty" ) == 0 ) + { + if( strcmp( aval, "yes" ) == 0 ) + dest->ifempty = TRUE; + else if( strcmp( aval, "no" ) == 0 ) + dest->ifempty = FALSE; + else + { + dest->ifempty = TRUE; + ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d; assumed \"yes\"\n", + aval, aname, line_number ); + } + } + else if( strcmp( aname, "olddir" ) == 0 ) + dest->olddir = normalize_pathname( aval ); + else if( strcmp( aname, "compresscmd" ) == 0 ) + dest->compresscmd = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + else if( strcmp( aname, "compressoptions" ) == 0 ) + dest->compressoptions = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + } + if( !dest->name ) + ERR( "Undefined destination name at line %d\n", line_number ); + if( !dest->file ) + ERR( "Undefined destination file at line %d\n", line_number ); + if( (!dest->name) || (!dest->file) || RP_INVALID == dest->rotate ) + { + if( dest->name ) g_free( dest->name ); + if( dest->file ) g_free( dest->file ); + if( dest->olddir ) g_free( dest->olddir ); + if( dest->compresscmd ) g_free( dest->compresscmd ); + if( dest->compressoptions ) g_free( dest->compressoptions ); + g_free( dest ); + return; + } + if( dest->compresscmd && !dest->compressoptions ) + dest->compressoptions = g_strdup( "$PATHNAME" ); - source->name = NULL; - source->type = ST_UNDEFINED; - memset( &source->udp, 0, sizeof(source->udp) ); - source->udp.sin_family = AF_INET; - source->udp.sin_port = htons( SYSLOG_PORT ); + dest->file_writers = NULL; + InitializeCriticalSection( &dest->cs_file_writers ); + destinations = g_list_append( destinations, dest ); +} + +/****************************************************************************** + * create_filter + * + * read attributes of element and initialize filter structure; + * save pointer to the structure in current_filter + */ +static void create_filter( int line_number, + const gchar** attribute_names, + const gchar** attribute_values ) +{ + const gchar *aname; + + current_filter = g_malloc0( sizeof(struct filter) ); + + for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) + { + if( strcmp( aname, "name" ) == 0 ) + current_filter->name = g_locale_from_utf8( *attribute_values, -1, NULL, NULL, NULL ); + } + if( !current_filter->name ) + { + ERR( "Undefined filter name at line %d\n", line_number ); + g_free( current_filter ); + current_filter = NULL; + } +} + +/****************************************************************************** + * init_filter + * + * parse sub-element of 'filter' and fill the structure current_filter + */ +static void init_filter( int line_number, + const gchar* element_name, + const gchar** attribute_names, + const gchar** attribute_values ) +{ + const gchar *aname, *aval; + int val = -1; + + if( strcmp( element_name, "facility" ) == 0 ) + { for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) { aval = *attribute_values; - if( strcmp( aname, "name" ) == 0 ) - source->name = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); - else if( strcmp( aname, "type" ) == 0 ) + if( strcmp( aname, "value" ) == 0 ) { - if( strcmp( aval, "internal" ) == 0 ) - source->type = ST_INTERNAL; - else if( strcmp( aval, "udp" ) == 0 ) - source->type = ST_UDP; + val = strtol( aval, NULL, 0 ); + if( val < 0 || val >= LOG_NFACILITIES ) + { + ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d\n", + aval, aname, line_number ); + return; + } } - else if( strcmp( aname, "interface" ) == 0 ) + else if( strcmp( aname, "name" ) == 0 ) { - struct hostent *he = gethostbyname( aval ); - if( !he ) + CODE *c; + for( c = facilitynames; c->c_name; c++ ) + if( strcmp( aval, c->c_name ) == 0 ) + { + val = LOG_FAC( c->c_val ); + break; + } + if( !c->c_name ) { - ERR( "Cannot resolve hostname %s; error %lu\n", aval, WSAGetLastError() ); - g_free( source ); + ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d\n", + aval, aname, line_number ); return; } - memcpy( &source->udp.sin_addr.s_addr, he->h_addr, he->h_length ); } - else if( strcmp( aname, "port" ) == 0 ) - source->udp.sin_port = htons( strtoul( aval, NULL, 0 ) ); } - - if( !source->name ) - ERR( "Undefined source name at line %d\n", line_number ); - if( ST_UNDEFINED == source->type ) - ERR( "Undefined source type at line %d\n", line_number ); - if( (!source->name) || ST_UNDEFINED == source->type ) + if( -1 == val ) { - g_free( source ); + ERR( "Undefined facility at line %d\n", line_number ); return; } - sources = g_list_append( sources, source ); + + current_filter->facilities[ val ] = TRUE; + return; } - else if( strcmp( element_name, "destination" ) == 0 ) - { - struct destination *dest = g_malloc0( sizeof(struct destination) ); + if( strcmp( element_name, "priority" ) == 0 ) + { for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) { aval = *attribute_values; - if( strcmp( aname, "name" ) == 0 ) - dest->name = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); - else if( strcmp( aname, "file" ) == 0 ) - dest->file = normalize_pathname( aval ); - else if( strcmp( aname, "rotate" ) == 0 ) + if( strcmp( aname, "value" ) == 0 ) { - if( strcmp( aval, "daily" ) == 0 ) - dest->rotate = RP_DAILY; - else if( strcmp( aval, "weekly" ) == 0 ) - dest->rotate = RP_WEEKLY; - else if( strcmp( aval, "monthly" ) == 0 ) - dest->rotate = RP_MONTHLY; - else + val = strtol( aval, NULL, 0 ); + if( val < 0 || val >= 8 ) { - ERR( "Invalid rotation period at line %d\n", line_number ); - dest->rotate = RP_INVALID; + ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d\n", + aval, aname, line_number ); + return; } } - else if( strcmp( aname, "size" ) == 0 ) - { - char *endptr; - dest->size = strtoul( aval, &endptr, 0 ); - if( 'k' == *endptr ) - dest->size *= 1024; - else if( 'M' == *endptr ) - dest->size *= 1024 * 1024; - } - else if( strcmp( aname, "backlogs" ) == 0 ) - dest->backlogs = strtoul( aval, NULL, 0 ); - else if( strcmp( aname, "ifempty" ) == 0 ) + else if( strcmp( aname, "name" ) == 0 ) { - if( strcmp( aval, "yes" ) == 0 ) - dest->ifempty = TRUE; - else if( strcmp( aval, "no" ) == 0 ) - dest->ifempty = FALSE; - else + CODE *c; + for( c = prioritynames; c->c_name; c++ ) + if( strcmp( aval, c->c_name ) == 0 ) + { + val = LOG_PRI( c->c_val ); + break; + } + if( !c->c_name ) { - dest->ifempty = TRUE; - ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d; assumed \"yes\"\n", + ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d\n", aval, aname, line_number ); + return; } } - else if( strcmp( aname, "olddir" ) == 0 ) - dest->olddir = normalize_pathname( aval ); - else if( strcmp( aname, "compresscmd" ) == 0 ) - dest->compresscmd = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); - else if( strcmp( aname, "compressoptions" ) == 0 ) - dest->compressoptions = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); } - if( !dest->name ) - ERR( "Undefined destination name at line %d\n", line_number ); - if( !dest->file ) - ERR( "Undefined destination file at line %d\n", line_number ); - if( (!dest->name) || (!dest->file) || RP_INVALID == dest->rotate ) + if( -1 == val ) { - if( dest->name ) g_free( dest->name ); - if( dest->file ) g_free( dest->file ); - if( dest->olddir ) g_free( dest->olddir ); - if( dest->compresscmd ) g_free( dest->compresscmd ); - if( dest->compressoptions ) g_free( dest->compressoptions ); - g_free( dest ); + ERR( "Undefined priority at line %d\n", line_number ); return; } - if( dest->compresscmd && !dest->compressoptions ) - dest->compressoptions = g_strdup( "$PATHNAME" ); - dest->file_writers = NULL; - InitializeCriticalSection( &dest->cs_file_writers ); + current_filter->priorities[ val ] = TRUE; + return; + } +} + +/****************************************************************************** + * create_logpath + * + * read attributes of element, initialize logpath_names structure and append + * if to the list of filters; + * logpath_names will be replaced with logpath structures after all the + * configuration has been read + */ +static void create_logpath( int line_number, + const gchar** attribute_names, + const gchar** attribute_values ) +{ + const gchar *aname; + struct logpath_names *logpath = g_malloc0( sizeof(struct logpath_names) ); - destinations = g_list_append( destinations, dest ); + for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) + { + const gchar *aval = *attribute_values; + if( strcmp( aname, "source" ) == 0 ) + logpath->source = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + else if( strcmp( aname, "filter" ) == 0 ) + logpath->filter = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + else if( strcmp( aname, "destination" ) == 0 ) + logpath->destination = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); } - else if( strcmp( element_name, "filter" ) == 0 ) + if( !logpath->source ) + ERR( "Undefined log path source at line %d\n", line_number ); + if( !logpath->destination ) + ERR( "Undefined log path destination at line %d\n", line_number ); + if( (!logpath->source) || (!logpath->destination) ) { - current_filter = g_malloc0( sizeof(struct filter) ); + if( logpath->source ) g_free( logpath->source ); + if( logpath->filter ) g_free( logpath->filter ); + if( logpath->destination ) g_free( logpath->destination ); + g_free( logpath ); + return; + } + logpaths = g_list_append( logpaths, logpath ); +} - for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) +/****************************************************************************** + * read_options + * + * read attributes of element and set corresponding options + */ +static void read_options( 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, "dns" ) == 0 ) { - if( strcmp( aname, "name" ) == 0 ) - current_filter->name = g_locale_from_utf8( *attribute_values, -1, NULL, NULL, NULL ); + if( strcmp( aval, "yes" ) == 0 ) + use_dns = TRUE; + else if( strcmp( aval, "no" ) == 0 ) + use_dns = FALSE; + else + ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d\n", aval, aname, line_number ); } - if( !current_filter->name ) + 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 ) + mark_message = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); + else if( strcmp( aname, "hold" ) == 0 ) { - ERR( "Undefined filter name at line %d\n", line_number ); - g_free( current_filter ); - current_filter = NULL; - return; + hold = strtoul( aval, NULL, 0 ); + if( hold < 1 ) + hold = 1; } + else if( strcmp( aname, "logdir" ) == 0 ) + logdir = normalize_pathname( aval ); } - else if( strcmp( element_name, "logpath" ) == 0 ) +} + +/****************************************************************************** + * create_purger_dir + * + * read attributes of element, initialize purger_dir structure and append + * it to the list of directories + */ +static void create_purger_dir( int line_number, + const gchar** attribute_names, + const gchar** attribute_values ) +{ + const gchar *aname; + struct purger_dir *pdir = g_malloc0( sizeof(struct purger_dir) ); + + for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) { - /* at first, fill logpaths list with logpath_names structures - and replace them later with logpath structures after configuration has been read - */ - struct logpath_names *logpath = g_malloc0( sizeof(struct logpath_names) ); + const gchar *aval = *attribute_values; + if( strcmp( aname, "directory" ) == 0 ) + pdir->directory = normalize_pathname( aval ); + else if( strcmp( aname, "keep_days" ) == 0 ) + pdir->keep_days = strtoul( aval, NULL, 0 ); + } + if( !pdir->directory ) + ERR( "Undefined purge directory at line %d\n", line_number ); + if( !pdir->keep_days ) + ERR( "Undefined keep_days parameter at line %d\n", line_number ); + if( (!pdir->directory) || (!pdir->keep_days) ) + { + if( pdir->directory ) g_free( pdir->directory ); + g_free( pdir ); + return; + } + purger_dirs = g_list_append( purger_dirs, pdir ); +} - for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) - { - aval = *attribute_values; - if( strcmp( aname, "source" ) == 0 ) - logpath->source = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); - else if( strcmp( aname, "filter" ) == 0 ) - logpath->filter = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); - else if( strcmp( aname, "destination" ) == 0 ) - logpath->destination = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); - } - if( !logpath->source ) - ERR( "Undefined log path source at line %d\n", line_number ); - if( !logpath->destination ) - ERR( "Undefined log path destination at line %d\n", line_number ); - if( (!logpath->source) || (!logpath->destination) ) - { - if( logpath->source ) g_free( logpath->source ); - if( logpath->filter ) g_free( logpath->filter ); - if( logpath->destination ) g_free( logpath->destination ); - g_free( logpath ); - return; - } - logpaths = g_list_append( logpaths, logpath ); +/****************************************************************************** + * xml_start_element + * + * parse configuration elements + */ +static void xml_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + int line_number; + + prolog_expected = FALSE; + + g_markup_parse_context_get_position( context, &line_number, NULL ); + + /* top-level elements */ + if( strcmp( element_name, "source" ) == 0 ) + { + create_source( line_number, attribute_names, attribute_values ); + } + else if( strcmp( element_name, "destination" ) == 0 ) + { + create_destination( line_number, attribute_names, attribute_values ); + } + else if( strcmp( element_name, "filter" ) == 0 ) + { + create_filter( line_number, attribute_names, attribute_values ); + } + else if( strcmp( element_name, "logpath" ) == 0 ) + { + create_logpath( line_number, attribute_names, attribute_values ); } else if( strcmp( element_name, "options" ) == 0 ) { - for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) - { - aval = *attribute_values; - if( strcmp( aname, "dns" ) == 0 ) - { - if( strcmp( aval, "yes" ) == 0 ) - use_dns = TRUE; - else if( strcmp( aval, "no" ) == 0 ) - use_dns = FALSE; - 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 ) - mark_message = g_locale_from_utf8( aval, -1, NULL, NULL, NULL ); - else if( strcmp( aname, "hold" ) == 0 ) - { - hold = strtoul( aval, NULL, 0 ); - if( hold < 1 ) - hold = 1; - } - else if( strcmp( aname, "logdir" ) == 0 ) - logdir = normalize_pathname( aval ); - } + read_options( line_number, attribute_names, attribute_values ); } else if( strcmp( element_name, "purge" ) == 0 ) { - struct purger_dir *pdir = g_malloc0( sizeof(struct purger_dir) ); - - for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) - { - aval = *attribute_values; - if( strcmp( aname, "directory" ) == 0 ) - pdir->directory = normalize_pathname( aval ); - else if( strcmp( aname, "keep_days" ) == 0 ) - pdir->keep_days = strtoul( aval, NULL, 0 ); - } - if( !pdir->directory ) - ERR( "Undefined purge directory at line %d\n", line_number ); - if( !pdir->keep_days ) - ERR( "Undefined keep_days parameter at line %d\n", line_number ); - if( (!pdir->directory) || (!pdir->keep_days) ) - { - if( pdir->directory ) g_free( pdir->directory ); - g_free( pdir ); - return; - } - purger_dirs = g_list_append( purger_dirs, pdir ); + create_purger_dir( line_number, attribute_names, attribute_values ); } else if( current_filter ) { /* sub-elements of filter */ - int val = -2; - - if( strcmp( element_name, "facility" ) == 0 ) - { - for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) - { - aval = *attribute_values; - if( strcmp( aname, "value" ) == 0 ) - { - val = strtol( aval, NULL, 0 ); - if( val < 0 || val >= LOG_NFACILITIES ) - { - val = -1; - break; - } - } - else if( strcmp( aname, "name" ) == 0 ) - { - CODE *c; - for( c = facilitynames; c->c_name; c++ ) - if( strcmp( aval, c->c_name ) == 0 ) - { - val = LOG_FAC( c->c_val ); - break; - } - if( !c->c_name ) - { - val = -1; - break; - } - } - } - if( -2 == val ) - ERR( "Undefined facility at line %d\n", line_number ); - else if( val != -1 ) - current_filter->facilities[ val ] = TRUE; - } - else if( strcmp( element_name, "priority" ) == 0 ) - { - for( ; (aname = *attribute_names) != NULL; attribute_names++, attribute_values++ ) - { - aval = *attribute_values; - if( strcmp( aname, "value" ) == 0 ) - { - val = strtol( aval, NULL, 0 ); - if( val < 0 || val >= 8 ) - { - val = -1; - break; - } - } - else if( strcmp( aname, "name" ) == 0 ) - { - CODE *c; - for( c = prioritynames; c->c_name; c++ ) - if( strcmp( aval, c->c_name ) == 0 ) - { - val = LOG_PRI( c->c_val ); - break; - } - if( !c->c_name ) - { - val = -1; - break; - } - } - } - if( -2 == val ) - ERR( "Undefined priority at line %d\n", line_number ); - else if( val != -1 ) - current_filter->priorities[ val ] = TRUE; - } - - if( -1 == val ) - ERR( "Invalid value \"%s\" of attribute \"%s\" at line %d\n", aval, aname, line_number ); + init_filter( line_number, element_name, attribute_names, attribute_values ); } } |