diff options
Diffstat (limited to 'common/elapi/elapi_resolve.c')
-rw-r--r-- | common/elapi/elapi_resolve.c | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/common/elapi/elapi_resolve.c b/common/elapi/elapi_resolve.c deleted file mode 100644 index ca2601b7..00000000 --- a/common/elapi/elapi_resolve.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - ELAPI - - Module contains functions to resolve the event. - - 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 <string.h> /* for strcmp() */ - -#include "elapi_priv.h" -#include "elapi_event.h" -#include "elapi_basic.h" -#include "trace.h" -#include "config.h" - -/*****************************************/ -/* Individual callbacks are defined here */ -/*****************************************/ -/* Timestamp resolution callback */ -static int elapi_timestamp_cb(struct elapi_resolve_data *resolver, - struct collection_item *item, - int *skip) -{ - int error = EOK; - char timestamp[TIME_ARRAY_SIZE + 1]; - int length; - - TRACE_FLOW_STRING("elapi_timestamp_cb", "Entry"); - - /* Construct the time stamp */ - length = strftime(timestamp, - TIME_ARRAY_SIZE, - (const char *)(col_get_item_data(item)), - &(resolver->local_time)); - - /* Update the time stamp item */ - error = col_modify_str_item(item, - NULL, - timestamp, - length + 1); - - TRACE_FLOW_NUMBER("elapi_timestamp_cb. Exit. Returning", error); - return error; -} - -/* UTC time resolution callback */ -static int elapi_utctime_cb(struct elapi_resolve_data *resolver, - struct collection_item *item, - int *skip) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_utctime_cb", "Entry"); - - /* Update the UTC item */ - error = col_modify_int_item(item, - NULL, - (int)(resolver->tm)); - - TRACE_FLOW_NUMBER("elapi_utctime_cb. Exit. Returning", error); - return error; -} - -/* Offset resolution callback */ -static int elapi_offset_cb(struct elapi_resolve_data *resolver, - struct collection_item *item, - int *skip) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_offset_cb", "Entry"); - - /* Update the offset item */ - error = col_modify_int_item(item, - NULL, - (int)(resolver->offset)); - - TRACE_FLOW_NUMBER("elapi_offset_cb. Exit. Returning", error); - return error; -} - -/* Message resolution callback */ -static int elapi_message_cb(struct elapi_resolve_data *resolver, - struct collection_item *item, - int *skip) -{ - - TRACE_FLOW_STRING("elapi_message_cb", "Entry"); - - /* Save pointer to message item */ - resolver->message = item; - - TRACE_FLOW_NUMBER("elapi_message_cb.", "Exit"); - return EOK; -} - - - -/*****************************************/ -/* Array of structures for resolution of - * the different event properties. - */ -struct elapi_resolve_list elapi_known_fields[] = { - { E_TIMESTAMP, { COL_TYPE_STRING, elapi_timestamp_cb }}, - { E_UTCTIME, { COL_TYPE_INTEGER, elapi_utctime_cb }}, - { E_OFFSET, { COL_TYPE_INTEGER, elapi_offset_cb }}, - { E_MESSAGE, { COL_TYPE_STRING, elapi_message_cb }}, - /* ADD NEW CALLBACKS HERE */ - { NULL, { COL_TYPE_ANY, NULL }} -}; - - - - -/*****************************************/ -/* A callback function to do substitutions - * of different properties as we copy the event. - */ -static int elapi_resolve_item(struct collection_item *item, - void *ext_data, - int *skip) -{ - int error = EOK; - struct elapi_resolve_data *resolver; - struct collection_item *res_item; - struct elapi_rslv_item_data *rslv_pair; - int res; - - TRACE_FLOW_STRING("elapi_resolve_item", "Entry"); - - /* Do we care about this field ? */ - if (strncmp(col_get_item_property(item, NULL), - E_PREFIX, - E_PREFIX_LEN) != 0) { - TRACE_FLOW_STRING("elapi_resolve_item. Skipping resoltion.", "Exit"); - return EOK; - } - - TRACE_FLOW_STRING("Item to resolve: ", col_get_item_property(item, NULL)); - - /* This is an internal field that might need resolution */ - resolver = (struct elapi_resolve_data *)ext_data; - - /* NOTE: This iteration loop uses advanced iterator - * capabilities. Read more about it before you decide - * to use this code as an example. - */ - while (1) { - - /* Advance to next item in the list */ - error = col_iterate_collection(resolver->handle->resolve_list, - &res_item); - if (error) { - TRACE_ERROR_NUMBER("Failed to iterate collection", error); - return error; - } - - /* Are we done ? This means we looped and did not find - * the item. */ - if (res_item == NULL) break; - - /* Compare items */ - res = col_compare_items(item, - res_item, - COL_CMPIN_PROP_EQU, - NULL); - if (res == 0) { - /* Item names are the same, so drill down and get expected type. */ - rslv_pair = *((struct elapi_rslv_item_data **)col_get_item_data(res_item)); - /* Make sure that types matched too */ - if (rslv_pair->type == col_get_item_type(item)) { - /* This is the item we need to resolve so resolve */ - error = rslv_pair->resolve_cb(resolver, - item, - skip); - if (error) { - TRACE_ERROR_NUMBER("Failed to resolve item", error); - return error; - } - - /* Pin down the iterator here */ - col_pin_iterator(resolver->handle->resolve_list); - - /* Break out of loop */ - break; - } - } - } - TRACE_FLOW_STRING("elapi_resolve_item", "Exit"); - return error; -} - -/* Message resolution function */ -int elapi_resolve_message(struct collection_item *item, - struct collection_item *event) -{ - int error = EOK; - struct elapi_data_out *serialized; - - TRACE_FLOW_STRING("elapi_resolve_message", "Entry"); - - /* I prefer to allocate it rather than do it on stack. - * The main reason is that I would have to memset - * the struct to init it. - * So why not just use the interface we already have. - */ - error = elapi_alloc_serialized_data(&serialized); - if (error) { - TRACE_ERROR_NUMBER("Failed to allocate serialized data", error); - return error; - } - - /* Call string substitution */ - error = elapi_sprintf(serialized, - (const char *)col_get_item_data(item), - event); - if (error) { - TRACE_ERROR_NUMBER("Failed to build message", error); - elapi_free_serialized_data(serialized); - return error; - } - - /* Put the resolved value into the item */ - error = col_modify_str_item(item, - NULL, - (char *)serialized->buffer, - serialized->length + 1); - - /* Clean data regardless of the result */ - elapi_free_serialized_data(serialized); - - if (error) { - TRACE_ERROR_NUMBER("Failed to modify message item", error); - return error; - } - - TRACE_FLOW_NUMBER("elapi_resolve_message. Exit. Returning", error); - return error; -} - -/* Resolve event */ -int elapi_resolve_event(struct collection_item **final_event, - struct collection_item *event, - struct elapi_dispatcher *handle) -{ - int error = EOK; - struct elapi_resolve_data resolver; - struct collection_item *new_event; - time_t local; - time_t utc; - - TRACE_FLOW_STRING("elapi_create_event_ctx", "Entry"); - - /* Prepare the resolver */ - resolver.message = NULL; - resolver.handle = handle; - /* Get seconds */ - resolver.tm = time(NULL); - /* Convert to local and UTC structured time */ - localtime_r(&resolver.tm, &(resolver.local_time)); - gmtime_r(&resolver.tm, &(resolver.utc_time)); - /* Convert back */ - utc = mktime(&(resolver.utc_time)); - local = mktime(&(resolver.local_time)); - /* Get offset - it is safe to typecast to int here */ - resolver.offset = (int)(difftime(local, utc)); - - /* NOTE: We will use FLATDOT mode. - * We will see what people have to say - * about this approach... - */ - error = col_copy_collection_with_cb(&new_event, - event, - NULL, - COL_COPY_FLATDOT, - elapi_resolve_item, - (void *)&resolver); - if (error) { - TRACE_ERROR_NUMBER("Failed to resolve the event", error); - return error; - } - - if (resolver.message) { - /* Now resolve message. We need to do it last since - * we do not know the order of the properties - * and message can be referencing properties - * that are later than message in the list - * and have not been resolved yet. - */ - error = elapi_resolve_message(resolver.message, - new_event); - if (error) { - TRACE_ERROR_NUMBER("Failed to resolve the event", error); - col_destroy_collection(new_event); - return error; - } - } - - *final_event = new_event; - - TRACE_FLOW_STRING("elapi_create_event_ctx", "Exit"); - return error; -} - -/* Function to initialize resolution list */ -int elapi_init_resolve_list(struct collection_iterator **list) -{ - int error = EOK; - struct elapi_resolve_list *current; - struct collection_item *col = NULL; - struct collection_iterator *iterator = NULL; - struct elapi_rslv_item_data *bin_data; - - TRACE_FLOW_STRING("elapi_init_resolve_list", "Entry"); - - /* Create collection of fields that we know how to process */ - error = col_create_collection(&col, - ELAPI_RESOLVE_ITEM, - COL_CLASS_ELAPI_RES_ITEM); - - if (error) { - TRACE_ERROR_NUMBER("Failed to create collection", error); - return error; - } - - /* Loop through the static array and turn it into a collection */ - current = elapi_known_fields; - while (current->name) { - bin_data = &(current->resolve_item); - error = col_add_binary_property(col, - NULL, - current->name, - (void *)&bin_data, - sizeof(struct elapi_rslv_item_data *)); - if (error) { - TRACE_ERROR_NUMBER("Failed to add item resolver", error); - col_destroy_collection(col); - return error; - } - - current++; - } - - /* Now bind iterator */ - error = col_bind_iterator(&iterator, col, COL_TRAVERSE_FLAT); - if (error) { - TRACE_ERROR_NUMBER("Failed to bind collection", error); - col_destroy_collection(col); - return error; - } - - /* We do not need the collection itself - we have iterator */ - col_destroy_collection(col); - - *list = iterator; - - TRACE_FLOW_STRING("elapi_init_resolve_list", "Exit"); - return error; -} |