diff options
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 000000000..2e93a355c --- /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"); +} |