diff options
Diffstat (limited to 'dispatcher/elapi_api.c')
-rw-r--r-- | dispatcher/elapi_api.c | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/dispatcher/elapi_api.c b/dispatcher/elapi_api.c index 919dee2..073059f 100644 --- a/dispatcher/elapi_api.c +++ b/dispatcher/elapi_api.c @@ -19,6 +19,7 @@ #include <stdio.h> +#include <stdarg.h> #include <string.h> #include <stdlib.h> #include <errno.h> @@ -106,6 +107,328 @@ int create_event(struct collection_item **event,char *name) } +/* Internal untility function to tokenize a string */ +static char *get_next_property(char *cursor,int *type, char **property, int *has_len) +{ + int adjust_by; + char *start; + + DEBUG_STRING("get_next_property","Entry"); + + DEBUG_STRING("Cursor",cursor); + + /* Initialize passed in data */ + *has_len = 0; + *property = NULL; + *type = ELAPI_TYPE_STRING; + + while((*cursor != '\0') && (*cursor != '%')) cursor++; + + /* End of string - we are done */ + if(*cursor == '\0') { + DEBUG_STRING("End of format - returning.",""); + return NULL; + } + + /* This is the beginning of the formatted token */ + cursor++; + if((*cursor == '*') && (*(cursor+1) == 's') && (*(cursor+2) == '(')) { + *type = ELAPI_TYPE_STRING; + *has_len = 1; + adjust_by = 3; + } + else if((*cursor == 's') && (*(cursor+1) == '(')) { + *type = ELAPI_TYPE_STRING; + adjust_by = 2; + } + else if(((*cursor == 'i')||(*cursor == 'd')) && (*(cursor+1) == '(')) { + *type = ELAPI_TYPE_INTEGER; + adjust_by = 2; + } + else if((*cursor == 'u') && (*(cursor+1) == '(')) { + *type = ELAPI_TYPE_INTEGER; + adjust_by = 2; + } + else if((*cursor == 'l') && ((*(cursor+1) == 'i')||(*(cursor+1) == 'd')) && (*(cursor+2) == '(')) { + *type = ELAPI_TYPE_LONG; + adjust_by = 3; + } + else if((*cursor == 'l') && (*(cursor+1) == 'u') && (*(cursor+2) == '(')) { + *type = ELAPI_TYPE_LONG; + adjust_by = 3; + } + else if(((*cursor == 'f')||(*cursor == 'e')) && (*(cursor+1) == '(')) { + *type = ELAPI_TYPE_DOUBLE; + adjust_by = 2; + } + else if((*cursor == 'b') && (*(cursor+1) == '(')) { + *type = ELAPI_TYPE_BINARY; + adjust_by = 2; + } + else { + DEBUG_STRING("Invalid type specifier format:",cursor); + return cursor; + } + + cursor += adjust_by; + start = cursor; + + /* Now we need to extruct the name of the property */ + /* We will not be nice here - the add_property will validate if the name is ok */ + while((*cursor != '\0') && (*cursor != ')')) cursor++; + + /* End of string - we are done */ + if((*cursor == '\0') || (cursor==start)) { + DEBUG_STRING("Bad property",""); + return cursor; + } + + *cursor ='\0'; + *property = start; + *cursor++; + + DEBUG_STRING("Returning Property:",*property); + DEBUG_NUMBER("Returning Type:",*type); + DEBUG_NUMBER("Returning Has length:",*has_len); + + + DEBUG_STRING("get_next_property","Exit"); + + return cursor; +} + +/* Creates collection - event based on the specified format */ +int construct_event(struct collection_item **event,char *name, char *format, ...) +{ + int error; + char *dup_fmt; + char *cursor; + int type; + char *property; + int has_len; + va_list args; + char *data_str; + int data_int; + unsigned int data_uint; + long data_long; + unsigned long data_ulong; + void *data_bin; + double data_dbl; + int length; + void *data; + + DEBUG_STRING("constuct_event","Entry"); + + /* Create event with timestamp */ + error = create_event(event,name); + if(error) { + DEBUG_NUMBER("create_event returned error:",error); + return error; + } + + /* Format is omitted just return */ + if(format == NULL) { + DEBUG_STRING("constuct_event","NULL format exit"); + return EOK; + } + + /* Process the format */ + /* Duplicate it */ + errno = 0; + dup_fmt = strdup(format); + if(dup_fmt == NULL) { + error = errno; + DEBUG_NUMBER("Failed to dup format:",error); + destroy_collection(*event); + return ENOMEM; + } + + va_start(args,format); + + cursor = dup_fmt; + while((cursor = get_next_property(cursor,&type,&property,&has_len)) != NULL) { + + /* Handle the case when the parsing failed */ + if(property == NULL) { + DEBUG_STRING("Error parsing:",dup_fmt); + free(dup_fmt); + destroy_collection(*event); + va_end(args); + return error; + } + + /* Get data */ + switch(type) { + + case ELAPI_TYPE_STRING: data_str = va_arg(args,char *); + data = (void *)data_str; + if(has_len) length = va_arg(args,int); + else length = strlen(data_str)+1; + DEBUG_STRING("Adding string:",data_str); + DEBUG_NUMBER("Length:",length); + break; + case ELAPI_TYPE_BINARY: data_bin = va_arg(args,void *); + data = (void *)data_bin; + length = va_arg(args,int); + break; + case ELAPI_TYPE_INTEGER: data_int = va_arg(args,int); + data = (void *)(&data_int); + length = sizeof(int); + break; + case ELAPI_TYPE_UNSIGNED: data_uint = va_arg(args,unsigned int); + data = (void *)(&data_uint); + length = sizeof(unsigned int); + break; + case ELAPI_TYPE_LONG: data_long = va_arg(args,long); + data = (void *)(&data_long); + length = sizeof(long); + break; + case ELAPI_TYPE_ULONG: data_ulong = va_arg(args,unsigned long); + data = (void *)(&data_ulong); + length = sizeof(unsigned long); + break; + case ELAPI_TYPE_DOUBLE: data_dbl = va_arg(args,double); + data = (void *)(&data_dbl); + length = sizeof(double); + break; + + default: + DEBUG_NUMBER("Unknown type",type); + continue; + } + + /* Add property to the event */ + error = add_any_property(*event, NULL, property, type, data,length); + if(error) { + DEBUG_STRING("Error adding property:",property); + DEBUG_NUMBER("Type :",type); + DEBUG_NUMBER("Length :",length); + free(dup_fmt); + destroy_collection(*event); + va_end(args); + return error; + } + } + + va_end(args); + free(dup_fmt); + DEBUG_STRING("constuct_event","NULL format exit"); + return EOK; +} + +/* Add/Updates the event properties based on the format */ +int modify_event(struct collection_item *event, int update, char *format, ...) +{ + int error; + char *dup_fmt; + char *cursor; + int type; + char *property; + int has_len; + va_list args; + char *data_str; + int data_int; + unsigned int data_uint; + long data_long; + unsigned long data_ulong; + void *data_bin; + double data_dbl; + int length; + void *data; + + DEBUG_STRING("modify_event","Entry"); + + + /* Format is omitted just return */ + if(format == NULL) { + DEBUG_STRING("modify_event","NULL format exit"); + return EOK; + } + + /* Process the format */ + /* Duplicate it */ + errno = 0; + dup_fmt = strdup(format); + if(dup_fmt == NULL) { + error = errno; + DEBUG_NUMBER("Failed to dup format:",error); + return ENOMEM; + } + + va_start(args,format); + + cursor = dup_fmt; + while((cursor = get_next_property(cursor,&type,&property,&has_len)) != NULL) { + + /* Handle the case when the parsing failed */ + if(property == NULL) { + DEBUG_STRING("Error parsing:",dup_fmt); + free(dup_fmt); + va_end(args); + return error; + } + + /* Get data */ + switch(type) { + + case ELAPI_TYPE_STRING: data_str = va_arg(args,char *); + data = (void *)data_str; + if(has_len) length = va_arg(args,int); + else length = strlen(data_str)+1; + DEBUG_STRING("Modifying string:",data_str); + DEBUG_NUMBER("Length:",length); + break; + case ELAPI_TYPE_BINARY: data_bin = va_arg(args,void *); + data = (void *)data_bin; + length = va_arg(args,int); + break; + case ELAPI_TYPE_INTEGER: data_int = va_arg(args,int); + data = (void *)(&data_int); + length = sizeof(int); + break; + case ELAPI_TYPE_UNSIGNED: data_uint = va_arg(args,unsigned int); + data = (void *)(&data_uint); + length = sizeof(unsigned int); + break; + case ELAPI_TYPE_LONG: data_long = va_arg(args,long); + data = (void *)(&data_long); + length = sizeof(long); + break; + case ELAPI_TYPE_ULONG: data_ulong = va_arg(args,unsigned long); + data = (void *)(&data_ulong); + length = sizeof(unsigned long); + break; + case ELAPI_TYPE_DOUBLE: data_dbl = va_arg(args,double); + data = (void *)(&data_dbl); + length = sizeof(double); + break; + + default: + DEBUG_NUMBER("Unknown type",type); + continue; + } + + /* Try to update property first but only on the high level */ + if(update) { + error = update_property(event, property, type, data, length, ELAPI_TRAVERSE_IGNORE); + if(error == ENOENT) error = add_any_property(event, NULL, property, type, data,length); + } + else error = add_any_property(event, NULL, property, type, data,length); + if(error) { + DEBUG_STRING("Error adding/updating property:",property); + DEBUG_NUMBER("Type :",type); + DEBUG_NUMBER("Length :",length); + free(dup_fmt); + va_end(args); + return error; + } + } + + va_end(args); + DEBUG_STRING("modify_event","NULL format exit"); + return EOK; +} + /* Log event */ void log_event(char *format_string,struct collection_item *event) { @@ -113,3 +436,5 @@ void log_event(char *format_string,struct collection_item *event) log_audit_event(global_dispatcher, format_string, event); DEBUG_STRING("log_event","Entry"); } + + |