summaryrefslogtreecommitdiffstats
path: root/dispatcher/elapi_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'dispatcher/elapi_api.c')
-rw-r--r--dispatcher/elapi_api.c325
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");
}
+
+