diff options
-rw-r--r-- | dispatcher/elapi_dispatcher.c | 25 | ||||
-rw-r--r-- | dispatcher/elapi_dispatcher_ut.c | 26 | ||||
-rw-r--r-- | sinks/elapi_sink.h | 6 | ||||
-rw-r--r-- | sinks/stderr/elapi_sink_stderr.c | 4 | ||||
-rw-r--r-- | sinks/syslog/elapi_sink_syslog.c | 10 |
5 files changed, 68 insertions, 3 deletions
diff --git a/dispatcher/elapi_dispatcher.c b/dispatcher/elapi_dispatcher.c index cecf5bf..ff1a275 100644 --- a/dispatcher/elapi_dispatcher.c +++ b/dispatcher/elapi_dispatcher.c @@ -119,12 +119,26 @@ static int load_sink(struct sink_descriptor *sink_data,char *sink_name) get_lib_info = (capability_fn)(dlsym(sink_data->lib_handle, SINK_ENTRY_POINT)); if ((lib_error = dlerror()) != NULL) { DEBUG_STRING("Dlsym returned error",lib_error); + dlclose(sink_data->lib_handle); return ELIBACC; } /* Init data */ get_lib_info(&(sink_data->sink_cpb_block)); + DEBUG_NUMBER("Instance:",sink_data->sink_cpb_block.instance); + DEBUG_NUMBER("Flags:",sink_data->sink_cpb_block.flags); + + /* Check if it is a single mode sink */ + if((sink_data->sink_cpb_block.instance > 0) && + ((sink_data->sink_cpb_block.flags & SINK_FLAG_LOAD_SINGLE) > 0)) { + /* This is the sink that should be loaded only once */ + /* We should fail and not even create the sink */ + DEBUG_STRING("Attempt to load the sink twice",""); + dlclose(sink_data->lib_handle); + return ELIBEXEC; + } + /* Call library initialization function */ init_sink(sink_data,ELAPI_SINK_OK); @@ -655,6 +669,17 @@ int alter_audit_dispatcher(struct dispatcher_handle *dispatcher, return error; case ELAPI_SINK_ACTION_DELETE: /* Try to delete the sink */ + error = get_item_and_do(dispatcher->sink_list, + sink, + ELAPI_TYPE_ANY, + ELAPI_TRAVERSE_DEFAULT, + close_sink_handler, + NULL); + if(error) { + DEBUG_NUMBER("alter_audit_dispatcher close sink returning",error); + return error; + } + error = delete_property(dispatcher->sink_list, sink, ELAPI_TYPE_ANY, diff --git a/dispatcher/elapi_dispatcher_ut.c b/dispatcher/elapi_dispatcher_ut.c index eec045b..bb848fa 100644 --- a/dispatcher/elapi_dispatcher_ut.c +++ b/dispatcher/elapi_dispatcher_ut.c @@ -111,6 +111,7 @@ int main() { int error = EOK; struct dispatcher_handle *dispatcher; + struct dispatcher_handle *dispatcher2; char *sinks[]= { "foo", "stderr", "bar", NULL }; printf("Test start\n"); @@ -164,6 +165,7 @@ int main() else printf("Expected failure. Error : %d\n",error); /* Adding new */ + printf("%s","=================\nAdding syslog - first time - expect success\n"); error = alter_audit_dispatcher(dispatcher,"syslog",ELAPI_SINK_ACTION_ADD); if(error != 0) printf("Expected success got failure %d\n",error); else printf("Success : %d\n",error); @@ -192,23 +194,41 @@ int main() print_collection(event); log_audit_event(dispatcher, event); - /* Pulse */ error = alter_audit_dispatcher(dispatcher,"syslog",ELAPI_SINK_ACTION_PULSE); if(error != 0) printf("Expected success got failure %d\n",error); else printf("Success : %d\n",error); - /* Disable */ - error = alter_audit_dispatcher(dispatcher,"syslog",ELAPI_SINK_ACTION_DISABLE); + + printf("%s","=================\nCreating another dispatcher - expect success\n"); + error = create_audit_dispatcher(&dispatcher2,"my_app",sinks,NULL,NULL); if(error != 0) printf("Expected success got failure %d\n",error); else printf("Success : %d\n",error); + printf("%s","=================\nAdding syslog sink to it - expect failure\n"); + error = alter_audit_dispatcher(dispatcher2,"syslog",ELAPI_SINK_ACTION_ADD); + if(error == 0) printf("%s","Expected failure got success\n"); + else printf("Expected failure. Error : %d\n",error); + + /* Delete */ error = alter_audit_dispatcher(dispatcher,"syslog",ELAPI_SINK_ACTION_DELETE); if(error != 0) printf("Expected success got failure %d\n",error); else printf("Success : %d\n",error); + + printf("%s","=================\nAdding syslog sink to it - now expect success\n"); + error = alter_audit_dispatcher(dispatcher2,"syslog",ELAPI_SINK_ACTION_ADD); + if(error != 0) printf("Expected success got failure %d\n",error); + else printf("Success : %d\n",error); + + /* Disable */ + error = alter_audit_dispatcher(dispatcher2,"syslog",ELAPI_SINK_ACTION_DISABLE); + if(error != 0) printf("Expected success got failure %d\n",error); + else printf("Success : %d\n",error); + destroy_audit_dispatcher(dispatcher); + destroy_audit_dispatcher(dispatcher2); destroy_collection(peer); destroy_collection(host); destroy_collection(socket); diff --git a/sinks/elapi_sink.h b/sinks/elapi_sink.h index 0c58c89..64ce235 100644 --- a/sinks/elapi_sink.h +++ b/sinks/elapi_sink.h @@ -16,6 +16,10 @@ #define SINK_NAME_TEMPLATE "libelapi_sink_%s.so" #define SINK_NEVER_RETRY -1 +/* Flags related to loading sinks */ +#define SINK_FLAG_NO_LIMIT 0x00000000 /* NO limits to loading and manipulating this sink - default */ +#define SINK_FLAG_LOAD_SINGLE 0x00000001 /* Only allow one instance of the sink per process */ + struct data_descriptor { char *appname; void *config; @@ -31,6 +35,8 @@ typedef void (*close_fn)(struct data_descriptor *dblock); struct sink_capability { int retry_interval; + int flags; + int instance; init_fn init_cb; cleanup_fn cleanup_cb; format_fn format_cb; diff --git a/sinks/stderr/elapi_sink_stderr.c b/sinks/stderr/elapi_sink_stderr.c index 17144ac..5f5555c 100644 --- a/sinks/stderr/elapi_sink_stderr.c +++ b/sinks/stderr/elapi_sink_stderr.c @@ -124,12 +124,16 @@ void get_sink_info(struct sink_capability *sink_cpb_block) DEBUG_STRING("get_sink_info","Entry"); sink_cpb_block->retry_interval = SINK_NEVER_RETRY; + sink_cpb_block->flags = SINK_FLAG_NO_LIMIT; + /* Instance never changes for this sink so one can load as many as he needs */ + sink_cpb_block->instance = 0; sink_cpb_block->init_cb = stderr_sink_init; sink_cpb_block->cleanup_cb = stderr_sink_cleanup; sink_cpb_block->format_cb = stderr_sink_format; sink_cpb_block->submit_cb = stderr_sink_submit; sink_cpb_block->close_cb = stderr_sink_close; + DEBUG_STRING("get_sink_info","Exit"); } diff --git a/sinks/syslog/elapi_sink_syslog.c b/sinks/syslog/elapi_sink_syslog.c index c9931a8..4d39838 100644 --- a/sinks/syslog/elapi_sink_syslog.c +++ b/sinks/syslog/elapi_sink_syslog.c @@ -10,6 +10,9 @@ #include "elapi_util.h" #include "elapi_ini.h" +/* Global variable - instance */ +static int instance = 0; + /* FIXME - this should be taken from the config.h generated by autotools */ #define SYSLOG_RETRY 60 /* @@ -135,6 +138,8 @@ static int init_config(struct data_descriptor *dblock) dblock->config = (void *)(conf_data); openlog(conf_data->ident,conf_data->option,conf_data->facility); + instance++; + DEBUG_NUMBER("syslog instance",instance); DEBUG_STRING("init_config","Entry"); return EOK; @@ -261,6 +266,9 @@ static void syslog_sink_close(struct data_descriptor *dblock) } closelog(); + DEBUG_STRING("Closed syslog",""); + if(instance) instance--; + DEBUG_NUMBER("syslog instance",instance); DEBUG_STRING("syslog_sink_close","Exit"); } @@ -292,6 +300,8 @@ void get_sink_info(struct sink_capability *sink_cpb_block) DEBUG_STRING("get_sink_info","Entry"); sink_cpb_block->retry_interval = SYSLOG_RETRY; + sink_cpb_block->flags = SINK_FLAG_LOAD_SINGLE; + sink_cpb_block->instance = instance; sink_cpb_block->init_cb = syslog_sink_init; sink_cpb_block->cleanup_cb = syslog_sink_cleanup; sink_cpb_block->format_cb = syslog_sink_format; |