diff options
author | Dmitri Pal <dpal@redhat.com> | 2009-08-07 15:50:34 -0400 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2009-08-12 12:24:27 -0400 |
commit | 1771d32e945b758326951384f0e17121042ad74e (patch) | |
tree | 070df00bcb1e049a1bdf794922b9b970479942a8 /common/elapi/elapi_internal.c | |
parent | d59ba3139bba2d28c1209f62c01a7017c26dd635 (diff) | |
download | sssd-1771d32e945b758326951384f0e17121042ad74e.tar.gz sssd-1771d32e945b758326951384f0e17121042ad74e.tar.bz2 sssd-1771d32e945b758326951384f0e17121042ad74e.zip |
ELAPI Next round of functionality - logging part of the interface
a) Added the main logging interface which
allows creating dispatcher and logging messages or events.
Can't actully log anything yet since the sinks are stubbed out.
b) Made default template be a part of the default
dispatcher.
c) Updated UNIT test.
d) Some of the calls are stubbed out but they are there
to indicate where next round of work will be.
Diffstat (limited to 'common/elapi/elapi_internal.c')
-rw-r--r-- | common/elapi/elapi_internal.c | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/common/elapi/elapi_internal.c b/common/elapi/elapi_internal.c new file mode 100644 index 00000000..2e93a355 --- /dev/null +++ b/common/elapi/elapi_internal.c @@ -0,0 +1,231 @@ +/* + ELAPI + + Implementation of the ELAPI logging interface. + + Copyright (C) Dmitri Pal <dpal@redhat.com> 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#define _GNU_SOURCE +#include <errno.h> /* for errors */ +#include <stdio.h> /* for printf() - temporarily */ + +#include "elapi_priv.h" +#include "elapi_event.h" +#include "elapi_sink.h" +#include "trace.h" +#include "config.h" +#include "ini_config.h" + +#include "collection_tools.h" /*temporarily */ + +/* Buffer size for time string */ +#define MAX_TIMESTR 200 + +/* I was told during review that I have to hard code the name. + * So it is hardcoded now. + */ +#define ELAPI_DEFAULT_ERROR_FILE "elapiconf.err" + +/* Handler for logging through the sinks */ +int elapi_internal_sink_handler(const char *sink, + int sink_len, + int type, + void *data, + int length, + void *passed_data, + int *stop) +{ + struct elapi_sink_context *sink_env; + TRACE_FLOW_STRING("elapi_internal_sink_handler", "Entry."); + + /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ + + sink_env = (struct elapi_sink_context *)(passed_data); + + if (type == COL_TYPE_COLLECTION) { + printf("\n\n\nPROCESSING EVENT:\n"); + col_debug_collection(sink_env->event, COL_TRAVERSE_DEFAULT); + } + else printf("Sink: %s\n", sink); + + TRACE_FLOW_STRING("elapi_internal_sink_handler", "Exit."); + return EOK; +} + +/* Internal sink cleanup function */ +int elapi_internal_sink_cleanup_handler(const char *sink, + int sink_len, + int type, + void *data, + int length, + void *passed_data, + int *stop) +{ + TRACE_FLOW_STRING("elapi_internal_sink_cleanup_handler", "Entry."); + + /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ + + if (type != COL_TYPE_COLLECTION) printf("Cleaning Sink: %s\n", sink); + + TRACE_FLOW_STRING("elapi_internal_sink_cleanup_handler", "Exit."); + return EOK; +} + +/* Function to add a sink to the collection */ +int elapi_internal_add_sink_to_collection(struct collection_item *sink_list, + char *sink, + char *appname) +{ + int error = EOK; + int found = 0; + struct sink_descriptor sink_data; + + TRACE_FLOW_STRING("elapi_internal_add_sink_to_collection", "Entry"); + error = col_is_item_in_collection(sink_list, + sink, + COL_TYPE_ANY, + COL_TRAVERSE_DEFAULT, + &found); + if (error) { + TRACE_ERROR_NUMBER("Search returned error", error); + return error; + } + + /* Check if it was found */ + if (found) { + TRACE_ERROR_NUMBER("Attempt to add an exiting sink.", ""); + return EINVAL; + } + + /* Save the pointer to application name into the sink's data block */ + sink_data.dblock.appname = appname; + TRACE_INFO_STRING("add_sink_to_list - saving appname:", sink_data.dblock.appname); + + /* Try to load the sink library */ + + /* FIXME - we need to have at least one sink implemented to enable this code. + * It is a placeholder for now. + error = load_sink(&sink_data, sink); + if (error != 0) { + DEBUG_NUMBER("Failed to load sink", error); + return error; + } + */ + + + /* We got a valid sink so add it to the collection */ + error = col_add_binary_property(sink_list, NULL, + sink, (void *)(&sink_data), + sizeof(struct sink_descriptor)); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to add sink data as property", error); + return error; + } + + TRACE_FLOW_NUMBER("elapi_internal_add_sink_to_collection returning", error); + return error; +} + +/* Function to create a list of sinks */ +int elapi_internal_construct_sink_list(struct elapi_dispatcher *handle) +{ + int error = EOK; + char **current_sink; + + TRACE_FLOW_STRING("elapi_internal_construct_sink_list", "Entry"); + + /* Allocate collection to store sinks */ + error = col_create_collection(&(handle->sink_list), + ELAPI_SINKS, + COL_CLASS_ELAPI_SINK); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to create sink collection. Error", error); + /* No cleanup here. + * The calling function will call a cleanup + * of the dispatcher as a whole.*/ + return error; + } + + current_sink = handle->sinks; + handle->sink_counter = 0; + + /* Add sinks as properties to the sink collection */ + while (*current_sink != NULL) { + + TRACE_INFO_STRING("Current sink", *current_sink); + TRACE_INFO_STRING("Will use appname:", handle->appname); + + /* Load sink */ + error = elapi_internal_add_sink_to_collection(handle->sink_list, + *current_sink, + handle->appname); + if ((error != 0) && (error != ELIBACC)) { + TRACE_ERROR_NUMBER("Failed to add sink", error); + /* No cleanup here. */ + return error; + } + + handle->sink_counter++; + current_sink++; + } + + /* Check if we have any sinks available */ + if (handle->sink_counter == 0) { + TRACE_ERROR_NUMBER("No sinks", ELIBACC); + /* No cleanup here. */ + /* Return "Cannot access a needed shared library" */ + return ELIBACC; + } + + TRACE_FLOW_STRING("elapi_internal_construct_sink_list", "Returning success"); + return EOK; +} + +/* If we failed to read configuration record this in the local file */ +void elapi_internal_dump_errors_to_file(struct collection_item *error_list) +{ + FILE *efile; + char timestr[MAX_TIMESTR]; + time_t time_in_sec; + struct tm *time_as_struct; + struct tm time_data; + + TRACE_FLOW_STRING("elapi_internal_dump_errors_to_file", "Entry point"); + + efile = fopen(ELAPI_DEFAULT_ERROR_FILE, "a"); + if (efile == NULL) { + TRACE_ERROR_STRING("No output available.", "Returning."); + return; + } + + time_in_sec = time(NULL); + time_as_struct = localtime_r(&time_in_sec, &time_data); + + fprintf(efile, "\n\n%*s\n\n", 80, "="); + + if ((time_as_struct != NULL) && + (strftime(timestr, sizeof(timestr), E_TIMESTAMP_FORMAT, time_as_struct) == 0)) { + fprintf(efile, "%s\n", timestr); + } + else { + TRACE_FLOW_STRING("elapi_internal_dump_errors_to_file", "Was not able to process time."); + } + + fprintf(efile, "\n"); + print_file_parsing_errors(efile, error_list); + + fclose(efile); + TRACE_FLOW_STRING("elapi_internal_dump_errors_to_file", "Exit"); +} |