diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2010-02-09 16:02:10 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2010-02-12 08:44:11 -0500 |
commit | 51572e9090d19b1f7cff8a10f70f75d7451ffdd4 (patch) | |
tree | d85a81c4a31c04627caab4e7827ce8fec04ce5d0 /common | |
parent | 1c244b0fd4f2db2fae784a66b2ad48a8aa623a8d (diff) | |
download | sssd-51572e9090d19b1f7cff8a10f70f75d7451ffdd4.tar.gz sssd-51572e9090d19b1f7cff8a10f70f75d7451ffdd4.tar.bz2 sssd-51572e9090d19b1f7cff8a10f70f75d7451ffdd4.zip |
Remove ELAPI from the SSSD repository
ELAPI now lives in its own project at
https://fedorahosted.org/ELAPI
Diffstat (limited to 'common')
40 files changed, 3 insertions, 8421 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index 29226ea5..cbd2866c 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -1,5 +1,5 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = trace collection ini dhash path_utils refarray elapi +SUBDIRS = trace collection ini dhash path_utils refarray dist_noinst_DATA = \ m4 @@ -12,13 +12,11 @@ libsssd_util_la_LIBADD = \ collection/libcollection.la \ ini/libini_config.la \ dhash/libdhash.la \ - refarray/libref_array.la \ - elapi/libelapi.la + refarray/libref_array.la libsssd_util_la_CFLAGS = $(AM_CFLAGS) \ -I ./collection \ -I ./ini \ -I ./dhash \ - -I ./elapi \ -I ./refarray \ -I ./trace endif diff --git a/common/configure.ac b/common/configure.ac index a017bcc7..5c55baa6 100644 --- a/common/configure.ac +++ b/common/configure.ac @@ -24,7 +24,7 @@ AS_IF([test ["$trace_level" -gt "0"] -a ["$trace_level" -lt "8"] ],[AC_SUBST([TR AC_CONFIG_FILES([Makefile trace/Makefile]) -AC_CONFIG_SUBDIRS([collection dhash ini path_utils refarray elapi]) +AC_CONFIG_SUBDIRS([collection dhash ini path_utils refarray]) AC_DEFUN([WITH_SINGLELIB], [ AC_ARG_WITH([singlelib], diff --git a/common/elapi/Makefile.am b/common/elapi/Makefile.am deleted file mode 100644 index 747a3883..00000000 --- a/common/elapi/Makefile.am +++ /dev/null @@ -1,76 +0,0 @@ -TRACE_LEVEL=@TRACE_VAR@ -DEFAULT_CONF_DIR=@elapiconfdir@ -DEFAULT_CONF_APP_DIR=@elapiconfappdir@ -APP_NAME=@appname@ -APP_NAME_SIZE=@appnamesize@ - -SUBDIRS = elapi_test - -topdir=$(srcdir)/.. -prvdrdir=$(srcdir)/providers - -AM_CFLAGS = \ - -DELAPI_DEFAULT_CONFIG_DIR=\"$(DEFAULT_CONF_DIR)\" \ - -DELAPI_DEFAULT_CONFIG_APP_DIR=\"$(DEFAULT_CONF_APP_DIR)\" \ - -DELAPI_DEFAULT_APP_NAME=\"$(APP_NAME)\" \ - -DELAPI_DEFAULT_APP_NAME_SIZE=$(APP_NAME_SIZE) - -if HAVE_GCC - AM_CFLAGS += \ - -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \ - -Wcast-align -Wwrite-strings -endif - -AM_CPPFLAGS = -I$(topdir) -I$(topdir)/ini -I$(topdir)/trace -I$(topdir)/collection \ - -I$(topdir)/elapi/providers/file $(TRACE_LEVEL) - -ACLOCAL_AMFLAGS = -I m4 - -# Set up the pkg-config file -pkgconfigdir = $(libdir)/pkgconfig -dist_noinst_DATA = \ - elapi.pc \ - m4 - -# Build libraries -noinst_LTLIBRARIES = libelapibasic.la libprovider.la libelapi.la - -libelapibasic_la_SOURCES = \ - elapi_basic.c \ - elapi_basic.h - -libprovider_la_SOURCES = \ - $(prvdrdir)/file/file_provider.c \ - $(prvdrdir)/file/file_provider.h \ - $(prvdrdir)/file/file_util.c \ - $(prvdrdir)/file/file_util.h \ - $(prvdrdir)/file/file_fmt_csv.c \ - $(prvdrdir)/file/file_fmt_csv.h - -libelapi_la_SOURCES = \ - elapi_event.c \ - elapi_log.c \ - elapi_internal.c \ - elapi_sink.c \ - elapi_resolve.c \ - elapi_async.c \ - elapi_subst.c \ - elapi_ioctl.c \ - elapi_event.h \ - elapi_priv.h \ - elapi_sink.h \ - elapi_log.h \ - elapi_async.h \ - elapi_net.h \ - elapi_ioctl.h \ - elapi_fd.h \ - elapi_tm.h \ - elapi_defines.h \ - elapi.h - -libelapi_la_LIBADD = libprovider.la libelapibasic.la - -tests: all - for subdir in $(SUBDIRS); do \ - $(MAKE) -C $$subdir $@; \ - done diff --git a/common/elapi/conf_macros.m4 b/common/elapi/conf_macros.m4 deleted file mode 100644 index e3de2b7f..00000000 --- a/common/elapi/conf_macros.m4 +++ /dev/null @@ -1,71 +0,0 @@ - -AC_DEFUN([WITH_CONFIG_DIR], - [ AC_ARG_WITH([config-dir], - [AC_HELP_STRING([--with-config-dir=DIR], - [The name of the default ELAPI config directory [SYSCONFDIR/elapi]] - ) - ] - ) - elapiconfdir="$sysconfdir/elapi" - if test x"$with_config_dir" != x; then - elapiconfdir=$with_config_dir - fi - AC_SUBST(elapiconfdir) - ]) - -AC_DEFUN([WITH_CONFIG_APP_DIR], - [ AC_ARG_WITH([config-app-dir], - [AC_HELP_STRING([--with-config-app-dir=DIR], - [The name of the ELAPI application config directory [SYSCONFDIR/elapi/apps.d]] - ) - ] - ) - elapiconfappdir="$sysconfdir/elapi/apps.d" - if test x"$with_config_app_dir" != x; then - elapiconfappdir=$with_config_app_dir - fi - AC_SUBST(elapiconfappdir) - ]) - -AC_DEFUN([WITH_APP_NAME], - [ AC_ARG_WITH([app-name], - [AC_HELP_STRING([--with-app-name=<name>], - [The name of the default ELAPI application [default]] - ) - ] - ) - appname="default" - if test x"$with_app_name" != x; then - appname=$with_app_name - fi - AC_SUBST(appname) - ]) - -AC_DEFUN([WITH_APP_NAME_SIZE], - [ AC_ARG_WITH([app-name-size], - [AC_HELP_STRING([--with-app-name-size=<size>], - [The maximum size of the name for an ELAPI application [127]] - ) - ] - ) - appnamesize="127" - if test x"$with_app_name_size" != x; then - appnamesize=$with_app_name_size - fi - AC_SUBST(appnamesize) - ]) - -AC_DEFUN([WITH_COMPAT], - [ AC_ARG_ENABLE([compat], - [AC_HELP_STRING([--enable-compat], - [use platform compatibility code]) - ], - , - [AC_CHECK_FUNC([getifaddrs], - AC_DEFINE([HAVE_GETIFADDRS], [1], - [Define if platform has getifaddrs()]) - ) - ] - ) - - ]) diff --git a/common/elapi/configure.ac b/common/elapi/configure.ac deleted file mode 100644 index 82be136d..00000000 --- a/common/elapi/configure.ac +++ /dev/null @@ -1,39 +0,0 @@ -AC_INIT([elapi],[0.0.1],[sssd-devel@lists.fedorahosted.org]) -AC_CONFIG_SRCDIR([elapi.h]) -AC_CONFIG_AUX_DIR([build]) -AM_INIT_AUTOMAKE([-Wall -Werror foreign]) -AC_PROG_CC -AC_PROG_LIBTOOL -AC_CONFIG_MACRO_DIR([m4]) -AC_PROG_INSTALL - -AM_CONDITIONAL([HAVE_GCC], [test "$ac_cv_prog_gcc" = yes]) - -m4_pattern_allow([AM_SILENT_RULES]) -AM_SILENT_RULES - -AC_CONFIG_HEADERS([config.h]) - - -# Enable trace build -AC_ARG_ENABLE([trace], - [AS_HELP_STRING([--enable-trace[=LEVEL]],[build with low level tracing enabled])], - [trace_level="$enableval"], - [trace_level="0"]) -AS_IF([test ["$trace_level" -gt "0"] -a ["$trace_level" -lt "8"] ],[AC_SUBST([TRACE_VAR],["-DTRACE_LEVEL=$trace_level"])]) - - -m4_include(conf_macros.m4) - -WITH_CONFIG_DIR -WITH_CONFIG_APP_DIR -WITH_APP_NAME -WITH_APP_NAME_SIZE -WITH_COMPAT - -m4_include(def_macros.m4) - -AC_CONFIG_SUBDIRS([elapi_test]) - -AC_CONFIG_FILES([Makefile elapi.pc]) -AC_OUTPUT diff --git a/common/elapi/def_macros.m4 b/common/elapi/def_macros.m4 deleted file mode 100644 index eca94dd2..00000000 --- a/common/elapi/def_macros.m4 +++ /dev/null @@ -1,5 +0,0 @@ -# Common defines for ELAPI and its unit test - -AC_DEFINE([MAX_LONG_STRING_LEN], [20], [Max length of the serialized long value]) -AC_DEFINE([MAX_DOUBLE_STRING_LEN], [22], [Max length of the serialized double value]) -AC_DEFINE([MAX_BOOL_STRING_LEN], [5], [Max length of the serialized bool value]) diff --git a/common/elapi/elapi.h b/common/elapi/elapi.h deleted file mode 100644 index 21f68d3f..00000000 --- a/common/elapi/elapi.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - ELAPI - - Aggregated header file for the ELAPI 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/>. -*/ - -#ifndef ELAPI_H -#define ELAPI_H - -#include "elapi_event.h" -#include "elapi_log.h" - -#endif diff --git a/common/elapi/elapi.pc.in b/common/elapi/elapi.pc.in deleted file mode 100644 index 73d2556e..00000000 --- a/common/elapi/elapi.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: @PACKAGE_NAME@ -Description: Event logging API (ELAPI) library -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lelapi -Cflags: -I${includedir} -URL: http://fedorahosted.org/sssd/ diff --git a/common/elapi/elapi_async.c b/common/elapi/elapi_async.c deleted file mode 100644 index 0c404c04..00000000 --- a/common/elapi/elapi_async.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - ELAPI - - Implementation for the ELAPI async processing 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 "elapi_async.h" -/* Private headers that deal with fd and tm structure definitions */ -#include "elapi_fd.h" -#include "elapi_tm.h" -#include "trace.h" -#include "config.h" - -/* Functions to set and get data from file descriptor data. */ -/* Functions return EINVAL if passed in argument is invalid. */ -int elapi_set_fd_priv(struct elapi_fd_data *fd_data, - void *priv_data_to_set) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_set_fd_priv", "Entry"); - - /* Check arguments */ - if (fd_data == NULL) { - TRACE_ERROR_NUMBER("Invalid argument. Error", EINVAL); - return EINVAL; - } - - fd_data->ext_data = priv_data_to_set; - - TRACE_FLOW_STRING("elapi_set_fd_priv", "Exit"); - return error; -} - -int elapi_get_fd_priv(struct elapi_fd_data *fd_data, - void **priv_data_to_get) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_get_fd_priv", "Entry"); - - /* Check arguments */ - if ((fd_data == NULL) || (priv_data_to_get == NULL)) { - TRACE_ERROR_NUMBER("Invalid argument. Error", EINVAL); - return EINVAL; - } - - *priv_data_to_get = fd_data->ext_data; - - TRACE_FLOW_STRING("elapi_get_fd_priv", "Exit"); - return error; -} - -/* Cleanup function */ -void elapi_destroy_fd_data(struct elapi_fd_data *fd_data) -{ - TRACE_FLOW_STRING("elapi_destroy_fd_data", "Entry"); - - - TRACE_FLOW_STRING("elapi_destroy_fd_data", "Exit"); -} - - -/* Functions to set and get custom data from timer data. */ -/* Functions return EINVAL if passed in argument is invalid. */ -int elapi_set_tm_priv(struct elapi_tm_data *tm_data, - void *priv_data_to_set) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_set_tm_priv", "Entry"); - - /* Check arguments */ - if (tm_data == NULL) { - TRACE_ERROR_NUMBER("Invalid argument. Error", EINVAL); - return EINVAL; - } - - tm_data->ext_data = priv_data_to_set; - - TRACE_FLOW_STRING("elapi_set_tm_priv", "Exit"); - return error; -} - -int elapi_get_tm_priv(struct elapi_tm_data *tm_data, - void **priv_data_to_get) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_get_tm_priv", "Entry"); - - /* Check arguments */ - if ((tm_data == NULL) || (priv_data_to_get == NULL)) { - TRACE_ERROR_NUMBER("Invalid argument. Error", EINVAL); - return EINVAL; - } - - *priv_data_to_get = tm_data->ext_data; - - TRACE_FLOW_STRING("elapi_get_tm_priv", "Exit"); - return error; -} - -/* Cleanup function */ -void elapi_destroy_tm_data(struct elapi_tm_data *tm_data) -{ - TRACE_FLOW_STRING("elapi_destroy_tm_data", "Entry"); - - - TRACE_FLOW_STRING("elapi_destroy_tm_data", "Exit"); -} - - -/* Public interfaces ELAPI exposes to handle fd or timer - * events (do not confuse with log events). - */ -int elapi_process_fd(struct elapi_fd_data *fd_data) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_process_fd", "Entry"); - - - TRACE_FLOW_STRING("elapi_process_fd", "Exit"); - return error; -} - -int elapi_process_tm(struct elapi_tm_data *tm_data) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_process_tm", "Entry"); - - - TRACE_FLOW_STRING("elapi_process_tm", "Exit"); - return error; -} diff --git a/common/elapi/elapi_async.h b/common/elapi/elapi_async.h deleted file mode 100644 index 21331766..00000000 --- a/common/elapi/elapi_async.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - ELAPI - - Header file for the ELAPI async processing 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/>. -*/ - -#ifndef ELAPI_ASYNC_H -#define ELAPI_ASYNC_H - -#include <sys/time.h> - -#define ELAPI_FD_READ 0x00000001 /* request to read */ -#define ELAPI_FD_WRITE 0x00000002 /* request to write */ - -/* Structure that holds ELAPI file descriptor's watch data */ -struct elapi_fd_data; - -/* Structure that holds ELAPI timer data */ -struct elapi_tm_data; - -/* Functions to set and get data from file descriptor data. */ -/* Functions return EINVAL if passed in argument is invalid. */ -int elapi_set_fd_priv(struct elapi_fd_data *fd_data, - void *priv_data_to_set); -int elapi_get_fd_priv(struct elapi_fd_data *fd_data, - void **priv_data_to_get); -/* Cleanup function */ -void elapi_destroy_fd_data(struct elapi_fd_data *fd_data); - -/* Functions to set and get custom data from timer data. */ -/* Functions return EINVAL if passed in argument is invalid. */ -int elapi_set_tm_priv(struct elapi_tm_data *tm_data, - void *priv_data_to_set); -int elapi_get_tm_priv(struct elapi_tm_data *tm_data, - void **priv_data_to_get); -/* Cleanup function */ -void elapi_destroy_tm_data(struct elapi_tm_data *tm_data); - -/* Public interfaces ELAPI exposes to handle fd or timer - * events (do not confuse with log events). - */ -int elapi_process_fd(struct elapi_fd_data *fd_data); -int elapi_process_tm(struct elapi_tm_data *tm_data); - -/* Signature of the function to add - * file descriptor into the event loop. - * Provided by caller of the ELAPI interface. - */ -typedef int (*elapi_add_fd)(int fd, - unsigned flags, - struct elapi_fd_data *fd_data, - void *ext_fd_data); - -/* Signature of the function to remove - * file descriptor from the event loop. - * Provided by caller of the ELAPI interface. - */ -typedef int (*elapi_rem_fd)(int fd, - struct elapi_fd_data *fd_data, - void *ext_fd_data); - -/* Signature of the function to set - * file descriptor for read/write operation. - * Provided by caller of the ELAPI interface. - */ -typedef int (*elapi_set_fd)(int fd, - unsigned flags, - struct elapi_fd_data *fd_data, - void *ext_fd_data); - - -/* Signature of the function to add timer. - * Provided by caller of the ELAPI interface. - */ -typedef int (*elapi_add_tm)(struct timeval tv, - struct elapi_tm_data *tm_data, - void *ext_tm_data); - -/* Signature of the function to add timer. - * Provided by caller of the ELAPI interface. - * Caller must be aware that the timeval strcuture - * is allocated on stack. - */ -typedef int (*elapi_rem_tm)(struct elapi_tm_data *tm_data, - void *ext_tm_data); - - - - -#endif diff --git a/common/elapi/elapi_basic.c b/common/elapi/elapi_basic.c deleted file mode 100644 index 8c7ddb7d..00000000 --- a/common/elapi/elapi_basic.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - ELAPI - - Basic output buffer manipulation routines. - - 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 <stdlib.h> /* for free() */ - -#include "elapi_basic.h" -#include "trace.h" -#include "config.h" - -/* Function to free serialized data */ -void elapi_free_serialized_data(struct elapi_data_out *out_data) -{ - TRACE_FLOW_STRING("elapi_free_serialized_data", "Entry"); - - if (out_data) { - free(out_data->buffer); - free(out_data); - } - - TRACE_FLOW_STRING("elapi_free_serialized_data", "Exit"); -} - -/* Allocate data structure */ -int elapi_alloc_serialized_data(struct elapi_data_out **out_data) -{ - int error; - - TRACE_FLOW_STRING("elapi_alloc_serialized_data", "Entry"); - - if (!out_data) { - TRACE_ERROR_STRING("Invalid argument", ""); - error = EINVAL; - } - else { - *out_data = (struct elapi_data_out *)calloc(1, - sizeof(struct elapi_data_out)); - if (*out_data == NULL) { - TRACE_ERROR_STRING("Failed to allocate memory", ""); - error = ENOMEM; - } - else error = EOK; - } - - TRACE_FLOW_NUMBER("elapi_alloc_serialized_data. Exit. Returning", error); - return error; -} - - -/* Grow buffer */ -int elapi_grow_data(struct elapi_data_out *out_data, - uint32_t len, - uint32_t block) -{ - int error = EOK; - unsigned char *newbuf = NULL; - - TRACE_FLOW_STRING("elapi_grow_data", "Entry"); - - TRACE_INFO_NUMBER("Current length: ", out_data->length); - TRACE_INFO_NUMBER("Current size: ", out_data->size); - TRACE_INFO_NUMBER("Length to have: ", len); - TRACE_INFO_NUMBER("Increment length: ", block); - - /* Grow buffer if needed */ - while (out_data->length + len >= out_data->size) { - newbuf = realloc(out_data->buffer, out_data->size + block); - if (newbuf == NULL) { - TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", ENOMEM); - return ENOMEM; - } - out_data->buffer = newbuf; - out_data->size += block; - TRACE_INFO_NUMBER("New size: ", out_data->size); - } - - TRACE_INFO_NUMBER("Final size: ", out_data->size); - TRACE_FLOW_NUMBER("elapi_grow_data. Exit. Returning", error); - return error; -} diff --git a/common/elapi/elapi_basic.h b/common/elapi/elapi_basic.h deleted file mode 100644 index 480ef1bf..00000000 --- a/common/elapi/elapi_basic.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - ELAPI - - Basic output buffer manipulation routines. - - 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/>. -*/ - -#ifndef ELAPI_BASIC_H -#define ELAPI_BASIC_H - -#include <stdint.h> -#include "elapi_defines.h" - -/* Generic data structure for the data output */ -struct elapi_data_out { - unsigned char *buffer; - uint32_t size; - uint32_t length; - uint32_t written; -}; - -/* Function to free serialized data */ -void elapi_free_serialized_data(struct elapi_data_out *out_data); - -/* Allocate data structure */ -int elapi_alloc_serialized_data(struct elapi_data_out **out_data); - -/* Function to add memory to the output buffer */ -int elapi_grow_data(struct elapi_data_out *out_data, - uint32_t len, - uint32_t block); - -#endif diff --git a/common/elapi/elapi_defines.h b/common/elapi/elapi_defines.h deleted file mode 100644 index 84030e86..00000000 --- a/common/elapi/elapi_defines.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - ELAPI - - Global defines for ELAPI - - 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/>. -*/ - -#ifndef ELAPI_DEFINES_H -#define ELAPI_DEFINES_H - -#ifndef EOK -#define EOK 0 -#endif - -#endif diff --git a/common/elapi/elapi_event.c b/common/elapi/elapi_event.c deleted file mode 100644 index ff739393..00000000 --- a/common/elapi/elapi_event.c +++ /dev/null @@ -1,1047 +0,0 @@ -/* - ELAPI - - Implementation of the ELAPI event 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 <sys/types.h> /* for getpid() */ -#include <unistd.h> /* for getpid() */ -#include <stdlib.h> /* for realloc() */ -#include <syslog.h> /* for contants releted to severity */ -#include <unistd.h> /* for gethostname() */ -#include <errno.h> /* for errors */ -#include <string.h> /* for memset() and other */ -#include <netdb.h> /* for gethostbyname() */ -#include <sys/socket.h> /* for inet_ntop() */ -#include <arpa/inet.h> /* for inet_ntop() */ -#include <ctype.h> /* for isspace() */ -#include <stdarg.h> /* for va_arg() */ -#include <string.h> /* for strndup() */ - -#include "elapi_priv.h" -#include "elapi_event.h" -#include "elapi_net.h" -#include "trace.h" -#include "config.h" - -#include "collection_tools.h" - -/* Internal return states from key processing */ -#define E_LIST_EMPTY 0 -#define E_LIST_ERROR 1 -#define E_LIST_LAST 2 -#define E_LIST_ADD 3 -#define E_LIST_REMOVE 4 - -#define LOCALHOSTDOMAIN "localhost.localdomain" -#define LOCALHOST "localhost" -#define LOCALADDRESS "127.0.0.1" -#define LOCALADDRESSV6 "::1" - -const char *undefined = "undefined"; -const char *str_yes = "yes"; -const char *str_no = "no"; -const char *str_true = "true"; -const char *str_false = "false"; - - -/* Function to add host identity information to the template */ -static int add_host_identity(struct collection_item *tpl, unsigned base) -{ - char hostname[NI_MAXHOST + 1]; - int error = EOK; - int gai_ret_host = 0; - int gai_ret_addr = 0; - char host[NI_MAXHOST]; - char address[NI_MAXHOST]; - char *hnm, *haddr; - ELAPI_ADDRLIST ifaddr; - ELAPI_ADDRITEM ifa; - struct sockaddr *addr; - int family; - int set_hostname = 0; - int set_ip = 0; - int used_this_ip = 0; - - TRACE_FLOW_STRING("add_host_identity", "Entry"); - - /* The goal here to collect information about the host. - * there is no need to actually use it for establishing - * any connections. - * It is a best effort attempt. - */ - - /* If we are not asked for hostname then say we already have it */ - if (!(base & E_HAVE_HOSTNAME)) set_hostname = 1; - /* If we are not asked for ip then say we already have it */ - if (!(base & E_HAVE_HOSTIP)) set_ip = 1; - - if (ELAPI_GET_ADDRLIST(&ifaddr) == EOK) { - - TRACE_FLOW_STRING("getifaddrs", "Ok"); - - /* Walk through linked list, maintaining head pointer so we - can free list later */ - ELAPI_GET_FIRST_ADDR_ITEM(ifaddr, ifa); - - while (ifa != NULL) { - - TRACE_FLOW_STRING("Top of the loop", ""); - - used_this_ip = 0; - - ELAPI_GET_ADDR(ifa, addr); - if (!addr) { - ELAPI_GET_NEXT_ADDR_ITEM(ifaddr, ifa); - continue; - } - - family = addr->sa_family; - - TRACE_FLOW_NUMBER("Family", family); - - /* For an AF_INET* interface address, display the address */ - if (family == AF_INET || family == AF_INET6) { - - TRACE_FLOW_NUMBER("Got right family", family); - - /* getnameinfo function claims that it returns NULL - * terminated strings. Well... - * We will trust it here and not clear memory using memset. - */ - - gai_ret_host = getnameinfo(addr, - (family == AF_INET) ? sizeof(struct sockaddr_in) : - sizeof(struct sockaddr_in6), - host, - NI_MAXHOST, - NULL, - 0, - 0 /* Gets host name */); - - gai_ret_addr = getnameinfo(addr, - (family == AF_INET) ? sizeof(struct sockaddr_in) : - sizeof(struct sockaddr_in6), - address, - NI_MAXHOST, - NULL, - 0, - NI_NUMERICHOST /* Gets address as string */); - - TRACE_INFO_STRING("Resolved host:", host); - TRACE_INFO_STRING("Resolved address:", address); - /* If we have not set host name set it */ - if(!set_hostname) { - - TRACE_FLOW_STRING("Host name is not set", ""); - - hnm = NULL; - /* Use host name returned by gethostname() as main host name */ - if (gethostname(hostname, NI_MAXHOST) == EOK) { - /* Make sure hostname is NULL terminated */ - hostname[NI_MAXHOST] = '\0'; - hnm = hostname; - } - else { - /* Were we able to get a host name ? */ - if (gai_ret_host == EOK) { - TRACE_INFO_STRING("getnameinfo returned:", host); - hnm = host; - } - } - - /* Do we have a host meaningful host name? */ - if ((hnm) && - ((strcasecmp(hnm, LOCALHOST) == 0 ) || - (strcasecmp(hnm, LOCALHOSTDOMAIN) == 0 ) || - (strcasecmp(hnm, address) == 0))) hnm = NULL; - - /* If host name is not NULL it would work for us */ - if (hnm) { - TRACE_INFO_STRING("Adding host name:", hnm); - error = col_add_str_property(tpl, NULL, E_HOSTNAME, hnm, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add host name. Error", error); - ELAPI_ADDR_LIST_CLEANUP(ifaddr); - return error; - } - /* Done with the name */ - set_hostname = 1; - } - } - - /* If we have not set processed ip address do it */ - if(!set_ip) { - - TRACE_FLOW_STRING("Address is not set", ""); - - haddr = NULL; - if (gai_ret_addr == EOK) { - TRACE_INFO_STRING("getnameinfo returned:", address); - if ((strcasecmp(address, LOCALADDRESS) != 0 ) && - (strcasecmp(address, LOCALADDRESSV6) != 0 )) { - TRACE_INFO_STRING("Not an unhelpful address", ""); - haddr = address; - } - } - - if (haddr) { - TRACE_INFO_STRING("Adding host address:", haddr); - error = col_add_str_property(tpl, NULL, E_HOSTIP, haddr, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add host name. Error", error); - ELAPI_ADDR_LIST_CLEANUP(ifaddr); - return error; - } - set_ip = 1; - used_this_ip = 1; - } - } - - /* If we have a name and we are told to deal with alias names */ - if ((set_hostname) && (base & E_HAVE_HOSTALIAS)) { - - TRACE_INFO_NUMBER("gai_ret_host:", gai_ret_host); - TRACE_INFO_STRING("host:", host); - TRACE_INFO_STRING("address:", address); - TRACE_INFO_STRING("they are:", ((strcasecmp(host, address) != 0) ? "different" : "same")); - - /* Do we have a host meaningful host name? */ - if ((gai_ret_host != EOK) || - ((gai_ret_host == EOK) && - ((strcasecmp(host, LOCALHOST) == 0 ) || - (strcasecmp(host, LOCALHOSTDOMAIN) == 0 ) || - (strcasecmp(host, address) == 0)))) hnm = NULL; - else hnm = host; - - if (hnm) { - TRACE_INFO_STRING("Adding alias host name:", hnm); - error = col_add_str_property(tpl, NULL, E_HOSTALIAS, hnm, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add host name. Error", error); - ELAPI_ADDR_LIST_CLEANUP(ifaddr); - return error; - } - } - } - - /* If we got then main IP and we are told to deal with opther IPs */ - if ((set_ip) && (base & E_HAVE_HOSTIPS) && (!used_this_ip)) { - - TRACE_INFO_STRING("Considering address:", address); - - /* Do we have a host meaningful IP */ - if ((gai_ret_addr != EOK) || - ((gai_ret_addr == EOK) && - ((strcasecmp(address, LOCALADDRESS) == 0 ) || - (strcasecmp(address, LOCALADDRESSV6) == 0 )))) haddr = NULL; - else haddr = address; - - if (haddr) { - TRACE_INFO_STRING("Adding alias host IP:", haddr); - error = col_add_str_property(tpl, NULL, E_HOSTIPS, haddr, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add host name. Error", error); - ELAPI_ADDR_LIST_CLEANUP(ifaddr); - return error; - } - } - } - } - TRACE_INFO_STRING("Moved to next", ""); - ELAPI_GET_NEXT_ADDR_ITEM(ifaddr, ifa); - TRACE_INFO_NUMBER("Moved to", ifa); - } - - ELAPI_ADDR_LIST_CLEANUP(ifaddr); - } - - /* Make sure that we really have the name after all */ - if (!set_hostname) { - TRACE_INFO_STRING("No host name using default:", undefined); - error = col_add_str_property(tpl, NULL, E_HOSTNAME, undefined, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add host name. Error", error); - return error; - } - } - - /* Make sure that we really have the IP after all */ - if (!set_ip) { - TRACE_INFO_STRING("No host name using default:", undefined); - error = col_add_str_property(tpl, NULL, E_HOSTIP, undefined, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add host name. Error", error); - return error; - } - } - - TRACE_FLOW_STRING("add_host_identity", "Exit"); - return error; -} - -/* Add base elements to template collection */ -static int add_base_elements(struct collection_item *tpl, unsigned base) -{ - int error = EOK; - unsigned pass_base; - - TRACE_FLOW_STRING("add_base_elements", "Entry"); - - /* Populate the template using base */ - if (base & E_HAVE_TIMESTAMP) { - /* Value is the format string for strftime() */ - error = col_add_str_property(tpl, NULL, E_TIMESTAMP, E_TIMESTAMP_FORMAT, sizeof(E_TIMESTAMP_FORMAT)); - if (error) { - TRACE_ERROR_NUMBER("Failed to add timestamp. Error", error); - return error; - } - } - - if (base & E_HAVE_UTCTIME) { - /* Value does not matter */ - error = col_add_int_property(tpl, NULL, E_UTCTIME, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add UTC time. Error", error); - return error; - } - } - - if (base & E_HAVE_OFFSET) { - /* Value does not matter */ - error = col_add_int_property(tpl, NULL, E_OFFSET, 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to add UTC time. Error", error); - return error; - } - } - - if (base & E_HAVE_PID) { - /* Value is the current pid */ - error = col_add_long_property(tpl, NULL, E_PID, (long)getpid()); - if (error) { - TRACE_ERROR_NUMBER("Failed to add pid. Error", error); - return error; - } - } - - if (base & E_HAVE_APPNAME) { - /* Value does not matter */ - error = col_add_str_property(tpl, NULL, E_APPNAME, "", 1); - if (error) { - TRACE_ERROR_NUMBER("Failed to add application name. Error", error); - return error; - } - } - - if (base & E_HAVE_SEVERITY) { - /* Value is the default severity */ - error = col_add_int_property(tpl, NULL, E_SEVERITY, LOG_USER | LOG_INFO); - if (error) { - TRACE_ERROR_NUMBER("Failed to add pid. Error", error); - return error; - } - } - - /* If we need to add aliases or other IPs call the function */ - if ((base & E_HAVE_HOSTNAME) || - (base & E_HAVE_HOSTIP) || - (base & E_HAVE_HOSTALIAS) || - (base & E_HAVE_HOSTIPS)) { - - pass_base = base; - - /* make sure we have extensions on top of the basic data */ - if ((base & E_HAVE_HOSTALIAS) && (!(base & E_HAVE_HOSTNAME))) pass_base |= E_HAVE_HOSTNAME; - if ((base & E_HAVE_HOSTIPS) && (!(base & E_HAVE_HOSTIP))) pass_base |= E_HAVE_HOSTIP; - - error = add_host_identity(tpl, pass_base); - if (error) { - TRACE_ERROR_NUMBER("Failed to add host identity. Error", error); - return error; - } - } - - TRACE_FLOW_STRING("add_base_elements", "Exit"); - return error; -} - - -/* Internal untility function to tokenize a string */ -static int interpret_key(char *key, - int *type, - char **property, - int *prop_len, - int *has_len, - int *bool_type) -{ - int adjust_by = 0; - char *start = NULL; - char *cursor = NULL; - char *end = NULL; - int ret = E_LIST_EMPTY; - - TRACE_FLOW_STRING("interpret_key", "Entry"); - - TRACE_INFO_STRING("Key", key); - - /* Initialize passed in data */ - *has_len = 0; - *property = NULL; - *type = COL_TYPE_STRING; - - cursor = key; - - while (isspace(*cursor)) cursor++; - - /* End of string - we are done */ - if (*cursor == '\0') { - TRACE_ERROR_STRING("Empty key - end of processing!", ""); - return E_LIST_EMPTY; - } - - /* This is the beginning of the formatted token */ - if (*cursor == '-') { - - /* This is a remove attribute case */ - - cursor++; - /* Skip spaces if any */ - while (isspace(*cursor)) cursor++; - - /* Mark the start of the actual property */ - start = cursor; - - /* Now we need to extract the name of the property */ - /* We will not be nice here - the add_property will validate if the name is ok */ - while ((*cursor != '\0') && (!isspace(*cursor))) cursor++; - - /* End of string - we are done */ - if (cursor == start) { - TRACE_ERROR_STRING("Invalid key - end of processing!", ""); - return E_LIST_EMPTY; - } - - *prop_len = cursor - start; - *property = start; - TRACE_INFO_STRING("We are told to remove the property!", *property); - ret = E_LIST_REMOVE; - } - else if (*cursor == '%') { - - /* We got a full key with format string */ - - cursor++; - if ((*cursor == '*') && (*(cursor+1) == 's') && (*(cursor+2) == '(')) { - *type = COL_TYPE_STRING; - *has_len = 1; - adjust_by = 3; - } - else if ((*cursor == 's') && (*(cursor+1) == '(')) { - *type = COL_TYPE_STRING; - adjust_by = 2; - } - else if (((*cursor == 'i')||(*cursor == 'd')) && (*(cursor+1) == '(')) { - *type = COL_TYPE_INTEGER; - adjust_by = 2; - } - else if ((*cursor == 'u') && (*(cursor+1) == '(')) { - *type = COL_TYPE_UNSIGNED; - adjust_by = 2; - } - else if ((*cursor == 'l') && ((*(cursor+1) == 'i')||(*(cursor+1) == 'd')) && (*(cursor+2) == '(')) { - *type = COL_TYPE_LONG; - adjust_by = 3; - } - else if ((*cursor == 'l') && (*(cursor+1) == 'u') && (*(cursor+2) == '(')) { - *type = COL_TYPE_ULONG; - adjust_by = 3; - } - else if (((*cursor == 'f')||(*cursor == 'e')) && (*(cursor+1) == '(')) { - *type = COL_TYPE_DOUBLE; - adjust_by = 2; - } - else if (((*cursor == 's') || (*cursor == 'd')) && (*(cursor+1) == 'b') && (*(cursor+2) == '(')) { - *type = COL_TYPE_BOOL; - adjust_by = 3; - if (*cursor == 's') *bool_type = 1; - else *bool_type = 0; - } - else if ((*cursor == 'n') && (*(cursor+1) == '(')) { - *type = COL_TYPE_BINARY; - adjust_by = 2; - } - else { - TRACE_ERROR_STRING("Invalid key - end of processing!", key); - return E_LIST_ERROR; - } - - cursor += adjust_by; - - /* Skip spaces if any */ - while (isspace(*cursor)) cursor++; - - start = cursor; - - /* Now we need to extract 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 != ')') && (!isspace(*cursor))) cursor++; - - /* End of string - we are done */ - if ((*cursor == '\0') || (cursor == start)) { - TRACE_ERROR_STRING("Invalid key - end of processing!", ""); - return E_LIST_EMPTY; - } - - end = cursor; - - /* Skip spaces if any */ - while (isspace(*cursor)) cursor++; - - /* Check that end of the string is in proper format */ - if ((*cursor != ')') && (*(cursor + 1) != '\0')) { - TRACE_ERROR_STRING("Invalid key - missing ')' .", key); - return E_LIST_ERROR; - } - - *property = start; - *prop_len = end - start; - - TRACE_INFO_STRING("Property:", *property); - TRACE_INFO_NUMBER("Property len:", *prop_len); - ret = E_LIST_ADD; - } - else { - /* Just got a key */ - /* Mark the start of the actual property */ - start = cursor; - - /* Now we need to extract the name of the property */ - /* We will not be nice here - the add_property will validate if the name is ok */ - while ((*cursor != '\0') && (!isspace(*cursor))) cursor++; - - /* End of string - we are done */ - if (cursor == start) { - TRACE_ERROR_STRING("Invalid key - end of processing!", ""); - return E_LIST_EMPTY; - } - - *prop_len = cursor - start; - *property = start; - TRACE_INFO_STRING("We are told to add/update the property (or last)!", *property); - - if(strncmp(*property, E_EOARG, *prop_len) == 0) ret = E_LIST_LAST; - else ret = E_LIST_ADD; - } - - TRACE_INFO_STRING("Returning Property:",*property); - TRACE_INFO_NUMBER("Returning Property len:", *prop_len); - TRACE_INFO_NUMBER("Returning Type:", *type); - TRACE_INFO_NUMBER("Returning Has length:", *has_len); - - - TRACE_FLOW_STRING("interpret_key", "Exit"); - - return ret; -} - -/* Make sure that the right string is given for bool value */ -static int convert_bool(char *data_str, unsigned char *data_bool) -{ - TRACE_FLOW_STRING("convert_bool", "Called"); - TRACE_INFO_STRING("Data", data_str); - - if ((strcasecmp(data_str, str_true) == 0) || - (strcasecmp(data_str, str_yes) == 0)) { - TRACE_INFO_STRING("Matched TRUE", ""); - *data_bool = '\1'; - return 1; - } - if ((strcasecmp(data_str, str_false) == 0) || - (strcasecmp(data_str, str_no) == 0)) { - TRACE_INFO_STRING("Matched FALSE", ""); - *data_bool = '\0'; - return 1; - } - TRACE_INFO_STRING("Matched NOTHING", ""); - return 0; -} - - -/* Process argument list */ -/* Update collection based on the passed in arguments */ -static int process_arg_list(struct collection_item *col, - va_list args) -{ - int error = EOK; - char *arg = NULL; - char *propcopy = NULL; - int ret = 0; - int type = 0; - char *property = NULL; - int prop_len = 0; - int has_len = 0; - int bool_type = 0; - char *data_str = NULL; - int data_int = 0; - unsigned int data_uint = 0; - long data_long = 0; - unsigned long data_ulong = 0; - void *data_bin = NULL; - double data_dbl = 0.; - int length = 0; - void *data = NULL; - unsigned char data_bool = '\0'; - - TRACE_FLOW_STRING("process_arg_list", "Entry."); - - /* We will break from the loop when we find the last item */ - while (1) { - - /* Get next key */ - arg = va_arg(args, char *); - - if (arg == NULL) { - TRACE_ERROR_STRING("Invalid NULL argument.", "Key can't be NULL"); - return EINVAL; - } - - /* Interpret the key. - * It can be just " key ", - * it can be " - key ", - * or it can be a formatted string - * something like " %*s( key )". - * Function will deal with all cases. - * Passed in variables initialized and updated inside - */ - ret = interpret_key(arg, - &type, - &property, - &prop_len, - &has_len, - &bool_type); - - if (ret == E_LIST_LAST) { - TRACE_INFO_STRING("Process found last key", arg); - break; - } - - if ((ret == E_LIST_ADD) || (ret == E_LIST_REMOVE)) { - /* We need to create a dup of the string */ - propcopy = malloc(prop_len + 1); - if (propcopy == NULL) { - TRACE_ERROR_STRING("Failed to allocate property", arg); - return ENOMEM; - } - - /* Copy property */ - memcpy(propcopy, property, prop_len); - propcopy[prop_len] = '\0'; - - TRACE_INFO_STRING("Processing property", propcopy); - - /* Are we supposed to add? */ - if (ret == E_LIST_ADD) { - - - /* NOTE: We are not going to check if the key value pairs - * are consistent. - * It can be made a bit more bullet proof by adding - * significant complexity to the code but I do not - * think it makes much sense to do so. - * There is no way to prevent the argument mismatch - * issues 100%. Printf can crash if aguments are - * missed or bad, so do we... - */ - - /* Get data */ - switch(type) { - - case COL_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; - TRACE_INFO_STRING("Adding string:", data_str); - TRACE_INFO_NUMBER("Length:",length); - break; - - case COL_TYPE_BINARY: data_bin = va_arg(args, void *); - data = (void *)data_bin; - length = va_arg(args, int); - break; - - case COL_TYPE_INTEGER: data_int = va_arg(args, int); - data = (void *)(&data_int); - length = sizeof(int); - break; - - case COL_TYPE_UNSIGNED: data_uint = va_arg(args, unsigned int); - data = (void *)(&data_uint); - length = sizeof(unsigned int); - break; - - case COL_TYPE_LONG: data_long = va_arg(args, long); - data = (void *)(&data_long); - length = sizeof(long); - break; - - case COL_TYPE_ULONG: data_ulong = va_arg(args, unsigned long); - data = (void *)(&data_ulong); - length = sizeof(unsigned long); - break; - - case COL_TYPE_DOUBLE: data_dbl = va_arg(args, double); - data = (void *)(&data_dbl); - length = sizeof(double); - break; - - case COL_TYPE_BOOL: if (bool_type) { - /* It is a string */ - data_str = va_arg(args,char *); - /* Check if it is a valid str */ - if (!(convert_bool(data_str, &data_bool))) { - TRACE_ERROR_STRING("Failed to to convert bool value", data_str); - free(propcopy); - return EINVAL; - } - } - else { - /* It is an int */ - data_int = va_arg(args, int); - if (data_int) data_bool = 1; - else data_bool = 0; - } - - data = (void *)(&data_bool); - length = sizeof(unsigned char); - break; - - default: - TRACE_ERROR_STRING("Invalid or unknown type", propcopy); - free(propcopy); - return EINVAL; - } - - /* Insert or update */ - error = col_insert_property_with_ref(col, - NULL, - COL_DSP_END, - NULL, - 0, - COL_INSERT_DUPOVER, - propcopy, - type, - data, - length, - NULL); - if (error) { - TRACE_ERROR_STRING("Error inserting property", property); - free(propcopy); - return error; - } - } - else { - /* Remove case */ - while (error != ENOENT) { - error = col_remove_item(col, - NULL, - COL_DSP_FIRSTDUP, - propcopy, - 0, - COL_TYPE_ANY); - if ((error) && (error != ENOENT)) { - TRACE_ERROR_STRING("Error deleting property", propcopy); - free(propcopy); - return error; - } - } - error = EOK; - } - free(propcopy); - } - else { - /* Errors related to key interpretation are handled here */ - TRACE_ERROR_STRING("Invalid arg", arg); - return EINVAL; - } - } /* end of arg processing loop */ - - TRACE_FLOW_STRING("process_arg_list", "Exit"); - return error; -} - - - -/*****************************************************************************/ -/* Create event template */ -int elapi_create_event_tplt_with_vargs(struct collection_item **tpl, - unsigned base, - va_list args) -{ - int error = EOK; - struct collection_item *new_tpl = NULL; - - TRACE_FLOW_STRING("elapi_create_event_tplt_with_vargs", "Entry"); - - if (tpl == NULL ) { - TRACE_ERROR_STRING("Template storage must be provided", ""); - return EINVAL; - } - - *tpl = NULL; - - /* Create collection */ - error = col_create_collection(&new_tpl, E_TEMPLATE_NAME, COL_CLASS_ELAPI_TEMPLATE); - if (error) { - TRACE_ERROR_NUMBER("Failed to create collection. Error", error); - return error; - } - - /* Add elements using base mask */ - error = add_base_elements(new_tpl, base); - if (error) { - TRACE_ERROR_NUMBER("Failed to add base elements. Error", error); - col_destroy_collection(new_tpl); - return error; - } - - /* Process variable argument list */ - error = process_arg_list(new_tpl, args); - - if (error) { - TRACE_ERROR_NUMBER("Failed to process argument list. Error", error); - col_destroy_collection(new_tpl); - return error; - } - - *tpl = new_tpl; - - TRACE_FLOW_STRING("elapi_create_event_tplt_with_vargs", "Exit"); - return error; -} - - -/* Create event template */ -int elapi_create_event_tplt(struct collection_item **tpl, - unsigned base, ...) -{ - int error = EOK; - va_list args; - - TRACE_FLOW_STRING("elapi_create_event_tplt", "Entry"); - - /* Process varible arguments */ - va_start(args, base); - - /* Create template using arguments */ - error = elapi_create_event_tplt_with_vargs(tpl, - base, - args); - - va_end(args); - - TRACE_FLOW_STRING("elapi_create_event_tplt", "Exit"); - return error; -} - -/* Function to destroy event template */ -void elapi_destroy_event_tplt(struct collection_item *tpl) -{ - TRACE_FLOW_STRING("elapi_destroy_event_tplt", "Entry"); - - col_destroy_collection(tpl); - - TRACE_FLOW_STRING("elapi_destroy_event_tplt", "Exit"); -} - - -/* Create event from template, colection and arguments */ -int elapi_create_event_with_vargs(struct collection_item **event, - struct collection_item *tpl, - struct collection_item *collection, - int mode, va_list args) -{ - int error = EOK; - struct collection_item *evt = NULL; - const char *alias; - - TRACE_FLOW_STRING("elapi_create_event_with_vargs", "Entry"); - - /* Check storage */ - if (event == NULL) { - TRACE_ERROR_STRING("Event storage must be provided", ""); - return EINVAL; - } - - *event = NULL; - - /* Create collection */ - error = col_create_collection(&evt, E_EVENT_NAME, COL_CLASS_ELAPI_EVENT); - if (error) { - TRACE_ERROR_NUMBER("Failed to create collection. Error", error); - return error; - } - - /* Add elements from the template */ - /* Check for template */ - if (tpl != NULL) { - error = col_add_collection_to_collection(evt, NULL, NULL, - (struct collection_item *)tpl, - COL_ADD_MODE_FLAT); - if (error) { - TRACE_ERROR_NUMBER("Failed to add elements from the template. Error", error); - col_destroy_collection(evt); - return error; - } - } - - /* Add elements from the collection */ - if (collection != NULL) { - /* If we are told to use FLAT DOT mode - * add collection with prefixing here. - */ - if (mode == COL_ADD_MODE_FLATDOT) { - alias = col_get_item_property(collection, NULL); - } - else alias = NULL; - - error = col_add_collection_to_collection(evt, NULL, alias, collection, mode); - if (error) { - TRACE_ERROR_NUMBER("Failed to add elements from external collection. Error", error); - col_destroy_collection(evt); - return error; - } - } - - /* Process variable argument list */ - error = process_arg_list(evt, args); - - if (error) { - TRACE_ERROR_NUMBER("Failed to process argument list. Error", error); - col_destroy_collection(evt); - return error; - } - - *event = evt; - - TRACE_FLOW_STRING("elapi_create_event_with_vargs", "Exit"); - return error; -} - - -/* Create event a wrapper around a function with arg list */ -int elapi_create_event(struct collection_item **event, - struct collection_item *tpl, - struct collection_item *collection, - int mode, ...) -{ - int error = EOK; - va_list args; - - TRACE_FLOW_STRING("elapi_create_event", "Entry"); - - va_start(args, mode); - - error = elapi_create_event_with_vargs(event, - tpl, - collection, - mode, - args); - va_end(args); - - - TRACE_FLOW_STRING("elapi_create_event", "Exit"); - return error; -} - -/* Add/Updates/Removes the event attributes based on the and provided key value pairs */ -int elapi_modify_event(struct collection_item *event, - struct collection_item *collection, - int mode, ...) -{ - int error = EOK; - va_list args; - const char *alias; - - TRACE_FLOW_STRING("elapi_modify_event", "Entry"); - - /* Check event */ - if (event == NULL ) { - TRACE_ERROR_STRING("Event must be provided", ""); - return EINVAL; - } - - /* Add elements from the template */ - if (collection != NULL) { - /* If we are told to use FLAT DOT mode - * add collection with prefixing here. - */ - if (mode == COL_ADD_MODE_FLATDOT) { - alias = col_get_item_property(collection, NULL); - } - else alias = NULL; - error = col_add_collection_to_collection(event, NULL, alias, collection, mode); - if (error) { - TRACE_ERROR_NUMBER("Failed to add elements from external collection. Error", error); - col_destroy_collection(event); - return error; - } - } - - /* Process varible arguments */ - va_start(args, mode); - - /* Process variable argument list */ - error = process_arg_list(event, args); - - va_end(args); - - if (error) { - TRACE_ERROR_NUMBER("Failed to process argument list. Error", error); - return error; - } - - TRACE_FLOW_STRING("elapi_modify_event", "Exit"); - return error; -} - -/* Create a copy of the event */ -int elapi_copy_event(struct collection_item **new_event, - struct collection_item *source_event) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_copy_event", "Entry"); - - error = col_copy_collection(new_event, - source_event, - NULL, - COL_COPY_NORMAL); - - TRACE_FLOW_NUMBER("elapi_copy_event. Exit Returning", error); - return error; -} - -/* Function to destroy event. */ -void elapi_destroy_event(struct collection_item *event) -{ - TRACE_FLOW_STRING("elapi_destroy_event", "Entry"); - - col_destroy_collection(event); - - TRACE_FLOW_STRING("elapi_destroy_event", "Exit"); -} diff --git a/common/elapi/elapi_event.h b/common/elapi/elapi_event.h deleted file mode 100644 index c83eec8b..00000000 --- a/common/elapi/elapi_event.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - ELAPI - - Header file for the ELAPI event 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/>. -*/ - -#ifndef ELAPI_EVENT_H -#define ELAPI_EVENT_H - -#include "collection.h" - -/* Possible predefined elements of the event. - * First letter R means that it is a property - * resolvable at the logging time. - */ - -#define E_TIMESTAMP "R_stamp__" /* string - the value is the format for strftime() - * default is standard format for current locale. */ -#define E_UTCTIME "R_time__" /* int - UTC time as unix time in seconds since 1970 */ -#define E_OFFSET "R_loco__" /* int - local time displacement */ -#define E_PID "__pid__" /* int - Process ID of the current process */ -#define E_APPNAME "__appnm__" /* string - Name of the current application */ -#define E_HOSTNAME "__host__" /* string - Name of the current host */ -#define E_HOSTIP "__ip__" /* string - IP address */ -#define E_SEVERITY "__sev__" /* int - Same as "priority" in syslog() */ -#define E_HOSTALIAS "__halias__" /* string - List of alternative host names */ -#define E_HOSTIPS "__iplist__" /* string - List of alternative IP addresses */ - -/* There is a special optional attribute of the event named "message". - * It is a string that contains text specific to each event. - * This string can contain placeholders that will be automatically - * replaced by the values that correspond to other attributes in - * the message. For example message can be: - * "Connected to remote %(server)". - * The token %(server) will be replaced by value - * in the attribute "server" in the event. - */ -#define E_MESSAGE "R_message__" - - -/* Standard prefix for internal resolvable attributes */ -#define E_PREFIX "R_" -#define E_PREFIX_LEN 2 - -/* Base argument in the template creation function is a bit mask. - * Each supported predefined element corresponds to its bit in - * the mask. - */ -#define E_HAVE_TIMESTAMP 0x00000001 -#define E_HAVE_UTCTIME 0x00000002 -#define E_HAVE_OFFSET 0x00000004 -#define E_HAVE_APPNAME 0x00000010 -#define E_HAVE_HOSTNAME 0x00000020 -#define E_HAVE_HOSTIP 0x00000040 -#define E_HAVE_SEVERITY 0x00000100 -#define E_HAVE_HOSTALIAS 0x00000200 -#define E_HAVE_HOSTIPS 0x00000400 -#define E_HAVE_PID 0x00001000 - -/* Convenient bitmasks */ -#define E_BASE_TIME ( E_HAVE_TIMESTAMP | E_HAVE_UTCTIME | E_HAVE_OFFSET) -#define E_BASE_HOST ( E_HAVE_HOSTIP | E_HAVE_HOSTNAME ) -#define E_BASE_APP ( E_HAVE_APPNAME | E_HAVE_PID ) -#define E_BASE_HOSTEXT ( E_HAVE_HOSTALIAS | E_HAVE_HOSTIPS ) -#define E_BASE_DEFV1 ( E_BASE_TIME | E_BASE_HOST | E_BASE_APP | E_HAVE_SEVERITY ) - - -/* The default time stamp format */ -#define E_TIMESTAMP_FORMAT "%F" - -#define TIME_ARRAY_SIZE 100 - - -/* End of arg list special value */ -#define E_EOARG "<EOARG>" - - - -/***************************************************************************/ -/* TREAD SAFE ELAPI EVENT API */ -/***************************************************************************/ - -/* In the thread safe API the caller is responsible for - * carrying context information. It is usually allocated - * when a "create" function is called - * and should be deleted using "destroy" function. - */ - -/* Create an event template. - * One can create an event template - * and specify what fields should be - * populated in the event at its creation. - * Possible supported fields are listed above. - * Base parameter specifies the base collection of - * attributes. See above. The value of 0 will default - * to the current version of default combination - * which might change as the API evolves. - * The variable list can be used to initialize template. - * It can be initialized by providing key value pairs. - * ...base, key, value, key, value); - * If the key does not contain format specifier - * the value should be a NULL terminated string. - * See examples for the specific syntax. - * If key starts with "-" like "-foo" - * it means that attribute should be removed. - * In this case the value should not be provided - * and next argument should be next key. - * The attributes selected by base argument will - * be internally and automatically initialized - * if there is no key - value pair provided. - * The timestamps will we overwritten each time - * the event is created so initializing them - * does not make sense unless you use the base - * that does not include them. - * The list of key value pairs MUST be terminated by special - * argument E_EOARG. - */ -int elapi_create_event_tplt(struct collection_item **tpl, - unsigned base, ...); - -/* Function to destroy event template */ -void elapi_destroy_event_tplt(struct collection_item *tpl); - -/***************************************************************************/ -/* Creates a new event using template (must be provided) - * and adds additional fields using collection - * if provided and/or key value pairs if provided. - * Mode specifies how the collection should be - * copied into event. - * See example for details about format specification. - */ -int elapi_create_event(struct collection_item **event, - struct collection_item *tpl, - struct collection_item *collection, - int mode, ...); - -/* Add/Updates/Removes the event attributes based on the and provided key value pairs */ -int elapi_modify_event(struct collection_item *event, - struct collection_item *collection, - int mode, ...); - -/* Create a copy of the event */ -int elapi_copy_event(struct collection_item **new_event, - struct collection_item *source_event); - -/* Function to destroy event. */ -void elapi_destroy_event(struct collection_item *event); - -/***************************************************************************/ -/* TREAD UNSAFE ELAPI EVENT API - for simple use cases */ -/***************************************************************************/ -/* Initializes default internal template */ -int elapi_set_default_tplt(unsigned base, ...); - -/* Retrieve default template */ -int elapi_get_default_tplt(struct collection_item **tpl); - - -/* This function will use internal default template. - * Hides all complexity from the caller. - */ -int elapi_create_simple_event(struct collection_item **event, ...); - - -#endif diff --git a/common/elapi/elapi_fd.h b/common/elapi/elapi_fd.h deleted file mode 100644 index 48f2722c..00000000 --- a/common/elapi/elapi_fd.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - ELAPI - - Private header to define internal structure of the ELAPI fd data. - - 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/>. -*/ - -#ifndef ELAPI_FD_H -#define ELAPI_FD_H - -#include "elapi_priv.h" - -/* Structure that holds ELAPI file descriptor's watch data */ -struct elapi_fd_data { - int fd; - void *ext_data; - struct elapi_dispatcher *handle; - struct elapi_sink_ctx *sink_ctx; - struct collection_item *event; -}; - -/* Create the fd data structure for the event */ -int elapi_create_fd_data(struct elapi_fd_data **fd_data, - int fd, - void *ext_data, - struct elapi_sink_ctx *sink_ctx, - struct collection_item *event); - - -#endif diff --git a/common/elapi/elapi_internal.c b/common/elapi/elapi_internal.c deleted file mode 100644 index fbbc0151..00000000 --- a/common/elapi/elapi_internal.c +++ /dev/null @@ -1,753 +0,0 @@ -/* - 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 <stdlib.h> /* for malloc() */ - -#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 targets */ -int elapi_tgt_cb(const char *target, - int target_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - int error = EOK; - struct elapi_tgt_data *target_data; - struct elapi_tgt_ctx *context; - - TRACE_FLOW_STRING("elapi_tgt_cb", "Entry."); - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - TRACE_FLOW_STRING("elapi_tgt_cb - skip header", "Exit."); - return EOK; - } - - target_data = (struct elapi_tgt_data *)(passed_data); - context = *((struct elapi_tgt_ctx **)(data)); - - /* Check if we need to log this event into this target */ - TRACE_INFO_NUMBER("EVENT IS LOGGED INTO:", target_data->target_mask); - TRACE_INFO_NUMBER("TARGET VALUE IS:", context->target_value); - - if ((target_data->target_mask & context->target_value) == 0) { - TRACE_INFO_STRING("Current event will NOT be logged into the target:", target); - return EOK; - } - - TRACE_INFO_STRING("Current event will be logged into the target:", target); - - /* Log event */ - error = elapi_tgt_submit(target_data->handle, context, target_data->event); - if (error) { - TRACE_ERROR_NUMBER("Failed to submit event to target", error); - return error; - } - - TRACE_FLOW_STRING("elapi_tgt_cb", "Exit."); - return EOK; -} - -/* Internal target cleanup function */ -int elapi_tgt_free_cb(const char *target, - int target_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - TRACE_FLOW_STRING("elapi_tgt_free_cb", "Entry."); - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - TRACE_FLOW_STRING("elapi_tgt_free_cb - skip header", "Exit."); - return EOK; - } - - elapi_tgt_destroy(*((struct elapi_tgt_ctx **)(data))); - - TRACE_FLOW_STRING("elapi_tgt_free_cb", "Exit."); - return EOK; -} - -/* Function to add a sink to the collection */ -/* This function belongs to this module. - * It adds sink into the collection - * of sinks inside dispatcher and puts - * reference into the target's reference list. - */ -/* FIXME - other arguments might be added later */ -int elapi_sink_add(struct collection_item **sink_ref, - const char *sink, - struct elapi_dispatcher *handle) -{ - int error = EOK; - struct elapi_sink_ctx *sink_context = NULL; - - TRACE_FLOW_STRING("elapi_sink_add", "Entry"); - - TRACE_INFO_STRING("Evaluating sink:", sink); - TRACE_INFO_NUMBER("Sink reference before call:", *sink_ref); - - /* Get the sink from the list */ - error = col_get_item(handle->sink_list, - sink, - COL_TYPE_ANY, - COL_TRAVERSE_DEFAULT, - sink_ref); - - TRACE_INFO_NUMBER("Sink evaluation returned", error); - TRACE_INFO_NUMBER("Sink reference after call:", *sink_ref); - - if (error) { - TRACE_ERROR_NUMBER("Search returned error", error); - return error; - } - - if (!(*sink_ref)) { - TRACE_FLOW_STRING("No such sink yet, adding new sink:", sink); - - /* Create a sink object */ - error = elapi_sink_create(&sink_context, sink, handle->ini_config, handle->appname); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to add sink data as property", error); - /* If create failed there is nothing to destroy */ - return error; - } - - /* If there was an internal error but sink is optional - * no error is returned but context is NULL. - * We need to check for this situation. - */ - if (sink_context) { - TRACE_FLOW_STRING("Loaded sink:", sink); - /* We got a valid sink so add it to the collection */ - error = col_add_binary_property_with_ref(handle->sink_list, - NULL, - sink, - (void *)(&sink_context), - sizeof(struct elapi_sink_ctx *), - sink_ref); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to add sink data as property", error); - elapi_sink_destroy(sink_context); - return error; - } - } - else { - *sink_ref = NULL; - TRACE_FLOW_STRING("Setting sink reference to NULL", ""); - } - } - - TRACE_FLOW_NUMBER("elapi_sink_add returning", error); - return error; -} - -/* Destroy target object */ -void elapi_tgt_destroy(struct elapi_tgt_ctx *context) -{ - TRACE_FLOW_STRING("elapi_tgt_destroy", "Entry."); - - TRACE_INFO_NUMBER("Target address in cleanup:", context); - - if (context) { - TRACE_INFO_STRING("Deleting the list of references to sinks", ""); - col_destroy_collection(context->sink_ref_list); - /* FIXME - add other cleanup for other things that will be a part - * of the target context. - */ - free(context); - } - - TRACE_FLOW_STRING("elapi_tgt_destroy", "Exit."); - -} - -/* Allocate target context and load sinks to it */ -int elapi_tgt_create(struct elapi_tgt_ctx **context, - const char *target, - struct elapi_dispatcher *handle) -{ - int error = EOK; - struct collection_item *sink_cfg_item = NULL; - struct collection_item *value_cfg_item = NULL; - struct elapi_tgt_ctx *target_context; - char **sinks; - char **current_sink; - struct collection_item *sink_ref; - unsigned count; - - TRACE_FLOW_STRING("elapi_tgt_create", "Entry."); - - /* Get list of sinks for this target from config */ - error = get_config_item(target, - ELAPI_SINKS, - handle->ini_config, - &sink_cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read configuration returned error", error); - return error; - } - - /* Do we have sinks? */ - if (sink_cfg_item == NULL) { - /* There is no list of targets this is bad configuration - return error */ - TRACE_ERROR_STRING("Required key is missing in the configuration.", "Fatal Error!"); - return ENOENT; - } - - /* Allocate context */ - target_context = (struct elapi_tgt_ctx *)calloc(1, sizeof(struct elapi_tgt_ctx)); - if (target_context == NULL) { - TRACE_ERROR_NUMBER("Memory allocation failed. Error", ENOMEM); - return ENOMEM; - } - - /* Assign target's value */ - error = get_config_item(target, - ELAPI_TARGET_VALUE, - handle->ini_config, - &value_cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read configuration returned error", error); - elapi_tgt_destroy(target_context); - return error; - } - - /* Do we have value? */ - if (value_cfg_item == NULL) { - TRACE_INFO_STRING("Value for target is not defined.", "Assume ANY."); - target_context->target_value = ELAPI_TARGET_ALL; - } - else { - target_context->target_value = (uint32_t)get_unsigned_config_value(value_cfg_item, - 1, - ELAPI_TARGET_ALL, - &error); - /* NOTE: I will check and fail here on error rather than do a best effort - * for now. We can switch to less rigorous checking when the INI - * validation library/utility becomes available. - */ - if (error) { - TRACE_ERROR_NUMBER("Failed to convert value form INI file", error); - elapi_tgt_destroy(target_context); - return error; - } - } - - TRACE_INFO_NUMBER("Value for target is:", target_context->target_value); - - - /* Allocate collection to store sink references for this target */ - error = col_create_collection(&(target_context->sink_ref_list), - ELAPI_SINK_REFS, - COL_CLASS_ELAPI_SINK_REF); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to create sink collection. Error", error); - elapi_tgt_destroy(target_context); - return error; - } - - /* Get list of sinks from config. Make sure we free it later */ - sinks = get_string_config_array(sink_cfg_item, NULL, NULL, NULL); - - /* For each sink in the list create sink context object and load sink */ - current_sink = sinks; - while (*current_sink != NULL) { - - TRACE_INFO_STRING("Current sink", *current_sink); - - /* Load sink if it is not loaded yet */ - sink_ref = NULL; - error = elapi_sink_add(&sink_ref, - *current_sink, - handle); - if (error) { - /* NOTE - we might decide to lax some of the checks - * like this later and be satisfied with at least one - * sink in the list. Subject for discussion... - */ - TRACE_ERROR_NUMBER("Failed to add sink", error); - elapi_tgt_destroy(target_context); - free_string_config_array(sinks); - return error; - } - - /* It might be that is was an error wit the optional sink so - * we need to check if the reference is not NULL; - */ - if (sink_ref) { - /* Add reference to it into the target object */ - error = col_add_binary_property(target_context->sink_ref_list, NULL, - *current_sink, (void *)(&sink_ref), - sizeof(struct collection_item *)); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to add sink reference", error); - elapi_tgt_destroy(target_context); - free_string_config_array(sinks); - return error; - } - } - else { - TRACE_INFO_STRING("Sink reference is NULL.", "Skipping the sink"); - } - current_sink++; - } - - free_string_config_array(sinks); - - /* Get count of the references in the list */ - error = col_get_collection_count(target_context->sink_ref_list, &count); - if (error) { - TRACE_ERROR_NUMBER("Failed to get count", error); - elapi_tgt_destroy(target_context); - return error; - } - - /* Check count */ - if (count <= 1) { - /* Nothing but header? - Bad! */ - TRACE_ERROR_NUMBER("No sinks loaded for target!", "This is a fatal error!"); - elapi_tgt_destroy(target_context); - return ENOENT; - } - - *context = target_context; - - TRACE_FLOW_STRING("elapi_tgt_create", "Exit."); - return EOK; -} - - -/* Function to create a list of targets */ -int elapi_tgt_mklist(struct elapi_dispatcher *handle) -{ - int error = EOK; - char **current_target; - struct elapi_tgt_ctx *context; - - - TRACE_FLOW_STRING("elapi_tgt_mklist", "Entry"); - - /* Allocate collection to store target */ - error = col_create_collection(&(handle->target_list), - ELAPI_TARGETS, - COL_CLASS_ELAPI_TARGET); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to create target collection. Error", error); - /* No cleanup here. - * The calling function will call a cleanup - * of the dispatcher as a whole.*/ - return error; - } - - /* 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_target = handle->targets; - handle->target_counter = 0; - - /* Add targets as properties to the target collection */ - while (*current_target != NULL) { - - TRACE_INFO_STRING("Current target", *current_target); - - /* Allocate target context and load sinks to it */ - context = NULL; - error = elapi_tgt_create(&context, - *current_target, - handle); - if (error) { - TRACE_ERROR_NUMBER("Failed to create target", error); - return error; - } - - TRACE_INFO_NUMBER("Target address:", context); - - /* Add created target to the list of targets */ - error = col_add_binary_property(handle->target_list, NULL, - *current_target, (void *)(&context), - sizeof(struct elapi_tgt_ctx *)); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to add sink data as property", error); - /* Need to clean allocated context here if we failed to add it */ - elapi_tgt_destroy(context); - return error; - } - - handle->target_counter++; - current_target++; - } - - /* Check if we have any targets available */ - if (handle->target_counter == 0) { - TRACE_ERROR_STRING("No targets", ""); - return ENOENT; - } - - TRACE_FLOW_STRING("elapi_tgt_mklist", "Returning success"); - return EOK; -} - -/* Submit event into the target */ -/* FIXME: do we need the whole dispatcher here? - * probably not. - * Need to sort out what parts of it we actually - * need and pass them explicitely. - * The point is that the target should not - * know or care about the dispatcher internals - * passing it here is a violation of the - * several desing patterns so it should be - * eventually fixed. - */ -int elapi_tgt_submit(struct elapi_dispatcher *handle, - struct elapi_tgt_ctx *context, - struct collection_item *event) -{ - int error = EOK; - struct collection_iterator *iterator; - struct collection_item *sink_item; - struct elapi_sink_ctx *ctx; - - TRACE_FLOW_STRING("elapi_tgt_submit", "Entry"); - - /* FIXME: General logic of the function - * should be the following: - * Get the list of the sinks - * For each sink - * Get its status - * Check if the sink is active - * If it is active log into it - * In error fail over to the next one - * else done - * else (not active) is it revivable? - * If so is it time to revive? - * If so mark as active and log into it - * If error fail over - * else done - * else fail over - * else fail over - * else fail over - * End for each sink - * - * This logic will be implemented - * in the later patches - * for now we will try - * all the sinks without checking status. - */ - - error = col_bind_iterator(&iterator, context->sink_ref_list, - COL_TRAVERSE_DEFAULT); - if (error) { - TRACE_ERROR_NUMBER("Failed to bind iterator.", error); - return error; - } - - while(1) { - /* Loop through the sink references */ - error = col_iterate_collection(iterator, &sink_item); - if (error) { - TRACE_ERROR_NUMBER("Error iterating event:", error); - col_unbind_iterator(iterator); - return error; - } - - /* Are we done ? */ - if (sink_item == NULL) break; - - /* Skip headers */ - if (col_get_item_type(sink_item) == COL_TYPE_COLLECTION) continue; - - - /* Dereference the sink item to get context */ - sink_item = *((struct collection_item **)(col_get_item_data(sink_item))); - ctx = *((struct elapi_sink_ctx **)(col_get_item_data(sink_item))); - - /* FIXME: Check the sink status */ - - /* FIXME other parameters might be required... */ - error = elapi_sink_submit(ctx, event); - if (error) { - TRACE_ERROR_NUMBER("Error submitting event:", error); - col_unbind_iterator(iterator); - return error; - } - - } - - col_unbind_iterator(iterator); - - TRACE_FLOW_STRING("elapi_tgt_submit", "Exit"); - return EOK; - -} - - -/* If we failed to read configuration record this in the local file */ -void elapi_dump_ini_err(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_dump_ini_err", "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_dump_ini_err", "Exit"); -} - -/****************************************************************************/ -/* Functions below are added for debugging purposes */ -/****************************************************************************/ -#ifdef ELAPI_VERBOSE - -void elapi_print_sink_ctx(struct elapi_sink_ctx *sink_context) -{ - /* This will not print well on 64 bit but it is just debugging - * so it is OK to have it. - */ - printf("Printing sink context using address %p\n", sink_context); - - printf("Mode: %s\n", sink_context->async_mode ? "true" : "false"); - if (sink_context->in_queue) col_print_collection(sink_context->in_queue); - else printf("Queue is not initialized.\n"); - - if (sink_context->pending) col_print_collection(sink_context->pending); - else printf("Pending list is not initialized.\n"); - - if (sink_context->sink_cfg.provider) printf("Provider: %s\n", - sink_context->sink_cfg.provider); - else printf("Provider is not defined.\n"); - - printf("Is provider required? %s\n", ((sink_context->sink_cfg.required > 0) ? "Yes" : "No")); - printf("On error: %s\n", ((sink_context->sink_cfg.onerror == 0) ? "retry" : "fail")); - printf("Timout: %d\n", sink_context->sink_cfg.timeout); - printf("Sync configuration: %s\n", sink_context->sink_cfg.synch ? "true" : "false"); - - if (sink_context->sink_cfg.priv_ctx) printf("Private context allocated.\n"); - else printf("Private context is NULL.\n"); - - if (sink_context->sink_cfg.libhandle) printf("Lib handle is allocated.\n"); - else printf("Lib handle is NULL.\n"); - - if (sink_context->sink_cfg.ability) printf("Capability function is present\n"); - else printf("NO capability function.\n"); - - if (sink_context->sink_cfg.cpb_cb.init_cb) printf("Init callback is OK.\n"); - else printf("Init callback is missing.\n"); - - if (sink_context->sink_cfg.cpb_cb.submit_cb) printf("Submit callback is OK.\n"); - else printf("Submit callback is missing.\n"); - - if (sink_context->sink_cfg.cpb_cb.close_cb) printf("Close callback is OK.\n"); - else printf("Close callback is missing.\n"); - - -} - -/* Handler for printing target internals */ -static int elapi_sink_ref_dbg_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - struct collection_item *sink_item; - struct elapi_sink_ctx *sink_context; - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - return EOK; - } - - sink_item = *((struct collection_item **)(data)); - - printf("\nReferenced sink name is: %s\n", col_get_item_property(sink_item, NULL)); - - sink_context = *((struct elapi_sink_ctx **)(col_get_item_data(sink_item))); - - elapi_print_sink_ctx(sink_context); - - - return EOK; -} - -/* Handler for printing sink internals */ -static int elapi_sink_dbg_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - struct elapi_sink_ctx *sink_context; - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - return EOK; - } - - sink_context = *((struct elapi_sink_ctx **)(data)); - - printf("\nSink name is: %s\n", sink); - - elapi_print_sink_ctx(sink_context); - - return EOK; -} - -/* Handler for printing target internals */ -static int elapi_tgt_dbg_cb(const char *target, - int target_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - struct elapi_tgt_ctx *context; - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - return EOK; - } - - context = *((struct elapi_tgt_ctx **)(data)); - - printf("\nTarget value for target \"%s\" is %d\n", target, context->target_value); - printf("\nReferenced sinks:\n\n"); - - (void)col_traverse_collection(context->sink_ref_list, - COL_TRAVERSE_ONELEVEL, - elapi_sink_ref_dbg_cb, - NULL); - - return EOK; -} - - - -/* Internal function to print dispatcher internals - useful for testing */ -void elapi_print_dispatcher(struct elapi_dispatcher *handle) -{ - char **current_target; - - printf("\nPRINTING DISPATCHER INTERNALS\n\n"); - - printf("Application name: %s\n", handle->appname != NULL ? handle->appname : "(null)"); - printf("List of target names:\n"); - - current_target = handle->targets; - while (*current_target != NULL) { - printf(" %s\n",*current_target); - current_target++; - } - - printf("Target counter: %d\n", handle->target_counter); - printf("\n\nTarget collection:\n\n"); - if (handle->target_list) col_debug_collection(handle->target_list, COL_TRAVERSE_DEFAULT); - - - printf("\n\nSink collection:\n\n"); - if (handle->sink_list) col_debug_collection(handle->sink_list, COL_TRAVERSE_DEFAULT); - printf("\n\nConfig collection:\n\n"); - if (handle->ini_config) col_debug_collection(handle->ini_config, COL_TRAVERSE_DEFAULT); - printf("\nDefault template:\n\n"); - if (handle->default_tpl) col_debug_collection(handle->default_tpl, COL_TRAVERSE_DEFAULT); - - printf("\n\nDeep target inspection:\n\n"); - if (handle->target_list) { - (void)col_traverse_collection(handle->target_list, - COL_TRAVERSE_ONELEVEL, - elapi_tgt_dbg_cb, - NULL); - } - printf("\n\nDeep sink inspection:\n\n"); - if (handle->sink_list) { - (void)col_traverse_collection(handle->sink_list, - COL_TRAVERSE_ONELEVEL, - elapi_sink_dbg_cb, - NULL); - } - /* FIXME: Async data... */ - - printf("DISPATCHER END\n\n"); - fflush(stdout); -} - -#endif diff --git a/common/elapi/elapi_ioctl.c b/common/elapi/elapi_ioctl.c deleted file mode 100644 index c2a42a17..00000000 --- a/common/elapi/elapi_ioctl.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - ELAPI - - Special platform specific functions related to networking - - 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 <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <stdlib.h> -#include <errno.h> - -#include "elapi_ioctl.h" -#include "trace.h" -#include "config.h" - -#ifndef HAVE_GETIFADDRS - -/* These functions are taken form Stevens's - * UNIX Network Programming Volume 1 - */ - -int elapi_get_addrlist(struct ifconf *ifc) -{ - int sockfd; - int length, lastlen; - int error; - char *buffer; - - TRACE_FLOW_STRING("elapi_get_addrlist", "Entry"); - - /* Open socket */ - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - - lastlen = 0; - length = INTERFACE_NUM_GUESS * sizeof(struct ifreq); - - /* Allocate right amount of memory */ - /* This is a trick from Stevens book */ - /* Search web for "get_ifi_info" to get original code */ - for ( ; ; ) { - - buffer = malloc(length); - ifc->ifc_len = length; - ifc->ifc_buf = buffer; - - /* Read list */ - if (ioctl(sockfd, SIOCGIFCONF, ifc) < 0) { - error = errno; - TRACE_INFO_NUMBER("Ioctl call failed", error); - if (error != EINVAL || lastlen != 0) { - free(buffer); - TRACE_ERROR_NUMBER("ioctl failed", error); - return error; - } - } else { - TRACE_INFO_NUMBER("Length returned", ifc->ifc_len); - TRACE_INFO_NUMBER("Previous length", lastlen); - /* Break if length is same */ - if (ifc->ifc_len == lastlen) break; - lastlen = ifc->ifc_len; - } - - /* Grow length */ - length += INTERFACE_NUM_INC * sizeof(struct ifreq); - free(buffer); - } - - TRACE_FLOW_STRING("elapi_get_addrlist", "Exit"); - return EOK; -} - -/* Get the variable part of the size of the address */ -static int elapi_get_addrlen(struct ifreq *ifr) -{ - int len; - - TRACE_FLOW_STRING("elapi_get_addrlen", "Entry"); - -#ifdef HAVE_SOCKADDR_SA_LEN - len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); -#else - switch (ifr->ifr_addr.sa_family) { -#ifdef IPV6 - case AF_INET6: - len = sizeof(struct sockaddr_in6); - break; -#endif - case AF_INET: - default: - len = sizeof(struct sockaddr); - break; - } -#endif /* HAVE_SOCKADDR_SA_LEN */ - - TRACE_FLOW_NUMBER("elapi_get_addrlen Returning", len); - return len; -} - -/* Get next address */ -struct ifreq *elapi_get_next_addr(struct ifconf *ifc, struct ifreq *current) -{ - char *ifr; - - TRACE_FLOW_STRING("elapi_get_next_addr", "Entry"); - - TRACE_INFO_NUMBER("Current ifi", current); - TRACE_INFO_NUMBER("Address", ¤t->ifr_addr); - - /* Move to the next item */ - ifr = (char *)current + sizeof(current->ifr_name) + elapi_get_addrlen(current); - - TRACE_INFO_NUMBER("New ifi", ifr); - - /* Check if we are beyond the end of the allocated area */ - /* Have to cast otherwise get warnings */ - if (ifr >= ((char *)ifc->ifc_buf + ifc->ifc_len)) ifr = NULL; - - TRACE_INFO_NUMBER("New ifi adjusted", ifr); - - TRACE_FLOW_STRING("elapi_get_next_addr", "Exit"); - - return (struct ifreq *)ifr; -} - - -#endif /* HAVE_GETIFADDRS */ diff --git a/common/elapi/elapi_ioctl.h b/common/elapi/elapi_ioctl.h deleted file mode 100644 index 409cb004..00000000 --- a/common/elapi/elapi_ioctl.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - ELAPI - - Header file for the ELAPI handling of network interfaces. - - 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/>. -*/ - -#ifndef ELAPI_IOCTL_H -#define ELAPI_IOCTL_H - -#include "config.h" - -#ifndef HAVE_GETIFADDRS - -#include "elapi_defines.h" -#include <net/if.h> - -/* Function prototypes */ -int elapi_get_addrlist(struct ifconf *ifc); -struct ifreq *elapi_get_next_addr(struct ifconf *ifc, struct ifreq *current); - -#define INTERFACE_NUM_GUESS 3 -#define INTERFACE_NUM_INC 1 - -#endif /* HAVE_GETIFADDRS */ - -#endif diff --git a/common/elapi/elapi_log.c b/common/elapi/elapi_log.c deleted file mode 100644 index 22a375b4..00000000 --- a/common/elapi/elapi_log.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - 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 <sys/types.h> /* for stat() */ -#include <sys/stat.h> /* for stat() */ -#include <unistd.h> /* for stat() */ -#include <errno.h> /* for errors */ -#include <string.h> /* for memset() and other */ -#include <stdarg.h> /* for va_arg() */ -#include <stdlib.h> /* for free() */ - - -#include "elapi_priv.h" -#include "elapi_event.h" -#include "elapi_log.h" -#include "ini_config.h" -#include "trace.h" -#include "config.h" - - -/* Pointer to default global dispatcher */ -struct elapi_dispatcher *global_dispatcher = NULL; - - -/* Per review I was told to hard cord this name. So be it... */ -#define ELAPI_CONFIG_FILE_NAME "elapi.conf" - -/* Default config file */ -static char default_config_file[] = ELAPI_DEFAULT_CONFIG_DIR "/" ELAPI_CONFIG_FILE_NAME; -/* Default config dir */ -static char default_config_dir[] = ELAPI_DEFAULT_CONFIG_APP_DIR; - - -/* Was a cleanup callback registered ? */ -static int elapi_close_registered = 0; - - -/* Internal function to log message using args */ -static int elapi_dsp_msg_with_vargs(uint32_t target, - struct elapi_dispatcher *dispatcher, - struct collection_item *tpl, - va_list args) -{ - int error = EOK; - struct collection_item *event; - - TRACE_FLOW_STRING("elapi_dsp_msg_with_vargs", "Entry"); - - if (!dispatcher) { - TRACE_ERROR_NUMBER("Invalid argument", EINVAL); - return EINVAL; - } - - /* Create event */ - error = elapi_create_event_with_vargs(&event, - tpl, - NULL, - 0, - args); - - if (error) { - TRACE_ERROR_NUMBER("Failed to create event", error); - return error; - } - - /* Now log event */ - error = elapi_dsp_log(target, dispatcher, event); - - /* Destroy event */ - elapi_destroy_event(event); - - if (error) { - TRACE_ERROR_NUMBER("Failed to log event", error); - return error; - } - - TRACE_FLOW_STRING("elapi_dsp_msg_with_vargs", "Exit"); - return error; -} - - -/********** Main functions of the interface **********/ -/* Function to free the async context */ -void elapi_destroy_asctx(struct elapi_async_ctx *ctx) -{ - TRACE_FLOW_STRING("elapi_destroy_asctx", "Entry"); - - free(ctx); - - TRACE_FLOW_STRING("elapi_destroy_asctx", "Exit"); -} - -/* Function to validate the consistency of the - * async context */ -static int elapi_check_asctx(struct elapi_async_ctx *ctx) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_check_asctx", "Entry"); - - /* Check callbacks */ - if ((ctx->add_fd_cb == NULL) || - (ctx->rem_fd_cb == NULL) || - (ctx->set_fd_cb == NULL) || - (ctx->add_tm_cb == NULL) || - (ctx->rem_tm_cb == NULL)) { - TRACE_ERROR_NUMBER("One of the callbacks is missing. Error", EINVAL); - return EINVAL; - } - - /* We do not check the data pointers. - * Why? Becuase thought it is a bad approach - * the data the callbacks will use - * can be a global (bad but can be!). - * So forcing caller to provide non-NULL - * data pointers is a bit too much. - */ - - TRACE_FLOW_STRING("elapi_check_asctx", "Exit"); - return error; -} - -/* Interface to create the async context */ -int elapi_create_asctx(struct elapi_async_ctx **ctx, - elapi_add_fd add_fd_cb, - elapi_rem_fd rem_fd_cb, - elapi_set_fd set_fd_cb, - void *ext_fd_data, - elapi_add_tm add_tm_cb, - elapi_rem_tm rem_tm_cb, - void *ext_tm_data) -{ - int error = EOK; - struct elapi_async_ctx *ctx_new; - - TRACE_FLOW_STRING("elapi_create_asctx", "Entry"); - - /* Allocate data, copy it and then check. - * Why this order? Why not check first - * without allocating memory and wasting - * cycles for it? - * Becuase the check function can be used - * in other place to validate that the context - * is correct. Allocating and freeing - * data is not an overhead since - * it is going to catch development - * error that would not exist in the final - * product. Otherwise the progam just - * would not run. - */ - - ctx_new = (struct elapi_async_ctx *)malloc(sizeof(struct elapi_async_ctx)); - if (ctx_new == NULL) { - TRACE_ERROR_NUMBER("Failed to allocate memory for the context", ENOMEM); - return ENOMEM; - } - - ctx_new->add_fd_cb = add_fd_cb; - ctx_new->rem_fd_cb = rem_fd_cb; - ctx_new->set_fd_cb = set_fd_cb; - ctx_new->add_tm_cb = add_tm_cb; - ctx_new->rem_tm_cb = rem_tm_cb; - ctx_new->ext_fd_data = ext_fd_data; - ctx_new->ext_tm_data = ext_tm_data; - - error = elapi_check_asctx(ctx_new); - if (error) { - TRACE_ERROR_NUMBER("Check context failed", error); - elapi_destroy_asctx(ctx_new); - return error; - } - - *ctx = ctx_new; - - TRACE_FLOW_STRING("elapi_create_asctx", "Exit"); - return error; -} - -/* Function to create a dispatcher */ -int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, - const char *appname, - const char *config_path, - struct elapi_async_ctx *async_ctx) -{ - struct elapi_dispatcher *handle = NULL; - struct collection_item *error_set = NULL; - int error = EOK; - struct collection_item *item = NULL; - const char *config_file = NULL; - const char *config_dir = NULL; - struct stat stat_data; - - TRACE_FLOW_STRING("elapi_create_dispatcher_adv", "Entry point"); - - /* Make sure the memory for handle is passed in */ - if (dispatcher == NULL) { - TRACE_ERROR_STRING("elapi_create_dispatcher_adv", "Invalid parameter."); - return EINVAL; - } - - /* Make sure we got the right constant */ - TRACE_INFO_NUMBER("ELAPI_DEFAULT_APP_NAME_SIZE = ", ELAPI_DEFAULT_APP_NAME_SIZE); - - if ((appname != NULL) && (strlen(appname) > ELAPI_DEFAULT_APP_NAME_SIZE)) { - TRACE_ERROR_STRING("elapi_create_dispatcher", "Application name is too long."); - return EINVAL; - } - - /* Check if context is valid */ - if (async_ctx) { - error = elapi_check_asctx(async_ctx); - if (error) { - TRACE_ERROR_NUMBER("Check context failed", error); - return error; - } - } - - /* Check what is passed in the config_path */ - if (config_path) { - /* What is it ? */ - if(stat(config_path, &stat_data)) { - error = errno; - TRACE_ERROR_NUMBER("Invalid path assume defaults. Error", error); - config_file = default_config_file; - config_dir = default_config_dir; - } - else { - if (S_ISREG(stat_data.st_mode)) { - config_file = config_path; - config_dir = NULL; - TRACE_INFO_STRING("Will use config file", config_file); - } - else if (S_ISDIR(stat_data.st_mode)) { - config_file = NULL; - config_dir = config_path; - TRACE_INFO_STRING("Will use directory", config_dir); - } - else { - config_file = default_config_file; - config_dir = default_config_dir; - } - } - } - else { - config_file = default_config_file; - config_dir = default_config_dir; - } - - TRACE_INFO_STRING("FILE:", config_file); - TRACE_INFO_STRING("DIR:", config_dir); - - /* Allocate memory */ - handle = (struct elapi_dispatcher *) calloc(1, sizeof(struct elapi_dispatcher)); - if (handle == NULL) { - TRACE_ERROR_NUMBER("Memory allocation failed. Error", ENOMEM); - return ENOMEM; - } - - /* Save application name in the handle */ - if (appname != NULL) handle->appname = strdup(appname); - else handle->appname = strdup(ELAPI_DEFAULT_APP_NAME); - - TRACE_FLOW_STRING("Application name:", handle->appname); - - /* Check error */ - if (handle->appname == NULL) { - TRACE_ERROR_NUMBER("Memory allocation failed. Error", ENOMEM); - elapi_destroy_dispatcher(handle); - return ENOMEM; - } - - /* Read the ELAPI configuration and store it in the dispatcher handle */ - error = config_for_app(handle->appname, - config_file, - config_dir, - &(handle->ini_config), - INI_STOP_ON_ANY, - &error_set); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read configuration returned error", error); - elapi_destroy_dispatcher(handle); - if (error_set) { - elapi_dump_ini_err(error_set); - free_ini_config_errors(error_set); - } - return error; - } - - /* Have to clean error set anyways */ - free_ini_config_errors(error_set); - - /* Get target list from configuration */ - error = get_config_item(ELAPI_DISPATCHER, - ELAPI_TARGETS, - handle->ini_config, - &item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read configuration returned error", error); - elapi_destroy_dispatcher(handle); - return error; - } - - /* Do we have targets? */ - if (item == NULL) { - /* There is no list of targets this is bad configuration - return error */ - TRACE_ERROR_STRING("No targets in the config file.", "Fatal error!"); - elapi_destroy_dispatcher(handle); - return ENOENT; - } - - /* Get one from config but make sure we free it later */ - handle->targets = get_string_config_array(item, NULL, NULL, NULL); - - /* Create the list of targets */ - error = elapi_tgt_mklist(handle); - if (error != EOK) { - TRACE_ERROR_NUMBER("Failed to create target list. Error", error); - elapi_destroy_dispatcher(handle); - return error; - } - - /* Populate async processing data if any */ - if (async_ctx) { - TRACE_INFO_STRING("Async data is present", ""); - handle->async_ctx = malloc(sizeof(struct elapi_async_ctx)); - if (handle->async_ctx != NULL) { - TRACE_ERROR_NUMBER("Failed to allocate async context", ENOMEM); - elapi_destroy_dispatcher(handle); - return ENOMEM; - } - /* Copy async data */ - memcpy(handle->async_ctx, async_ctx, sizeof(struct elapi_async_ctx)); - } - else { - TRACE_INFO_STRING("No async data present", ""); - handle->async_ctx = NULL; - } - - /* Build the list of the items we know how to resolve */ - error = elapi_init_resolve_list(&(handle->resolve_list)); - if (error != EOK) { - TRACE_ERROR_NUMBER("Failed to create list of resolvers. Error", error); - elapi_destroy_dispatcher(handle); - return error; - } - - *dispatcher = handle; - - TRACE_FLOW_STRING("elapi_create_dispatcher_adv", "Returning Success."); - return EOK; - -} - -/* Simple dispatcher */ -int elapi_create_dispatcher(struct elapi_dispatcher **dispatcher, - const char *appname, - const char *config_path) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_create_dispatcher", "Entry."); - - /* Will have more parmeters in future */ - error = elapi_create_dispatcher_adv(dispatcher, - appname, - config_path, - NULL); - - TRACE_FLOW_STRING("elapi_create_dispatcher", "Exit."); - return error; - -} - -/* Function to clean memory associated with the dispatcher */ -void elapi_destroy_dispatcher(struct elapi_dispatcher *dispatcher) -{ - TRACE_FLOW_STRING("elapi_destroy_dispatcher", "Entry."); - - if (dispatcher) { - TRACE_INFO_STRING("Deleting template if any...", ""); - col_destroy_collection(dispatcher->default_tpl); - - if (dispatcher->target_list) { - TRACE_INFO_STRING("Closing target list.", ""); - (void)col_traverse_collection(dispatcher->target_list, - COL_TRAVERSE_ONELEVEL, - elapi_tgt_free_cb, - NULL); - - TRACE_INFO_STRING("Deleting target list.", ""); - col_destroy_collection(dispatcher->target_list); - } - - if (dispatcher->sink_list) { - TRACE_INFO_STRING("Closing sink list.", ""); - (void)col_traverse_collection(dispatcher->sink_list, - COL_TRAVERSE_ONELEVEL, - elapi_sink_free_cb, - NULL); - TRACE_INFO_STRING("Deleting target list.", ""); - col_destroy_collection(dispatcher->sink_list); - } - - TRACE_INFO_STRING("Freeing application name.", ""); - free(dispatcher->appname); - TRACE_INFO_STRING("Freeing async context.", ""); - free(dispatcher->async_ctx); - TRACE_INFO_STRING("Freeing config.", ""); - free_ini_config(dispatcher->ini_config); - TRACE_INFO_STRING("Deleting targets name array.", ""); - free_string_config_array(dispatcher->targets); - TRACE_INFO_STRING("Unbind resolver iterator.", ""); - col_unbind_iterator(dispatcher->resolve_list); - TRACE_INFO_STRING("Freeing dispatcher.", ""); - free(dispatcher); - } - - TRACE_FLOW_STRING("elapi_destroy_dispatcher", "Exit."); -} - -/* Function to log an event */ -int elapi_dsp_log(uint32_t target, - struct elapi_dispatcher *dispatcher, - struct collection_item *event) -{ - int error = EOK; - struct elapi_tgt_data target_data; - struct collection_item *resolved_event; - - TRACE_FLOW_STRING("elapi_dsp_log", "Entry"); - - if ((dispatcher == NULL) || - (event == NULL)) { - TRACE_ERROR_STRING("elapi_dsp_log", "ERROR Invalid argument"); - return EINVAL; - } - - /* Create a resolved event */ - error = elapi_resolve_event(&resolved_event, event, dispatcher); - if (error) { - TRACE_ERROR_NUMBER("Failed to create event context. Error", error); - return error; - } - - /* Wrap parameters into one argument and pass on */ - target_data.handle = dispatcher; - target_data.event = resolved_event; - target_data.target_mask = target; - - TRACE_INFO_NUMBER("Target mask is:", target_data.target_mask); - - /* Logging an event is just iterating through the targets and calling a callback */ - error = col_traverse_collection(dispatcher->target_list, - COL_TRAVERSE_ONELEVEL, - elapi_tgt_cb, - (void *)(&target_data)); - - elapi_destroy_event(resolved_event); - - TRACE_FLOW_NUMBER("elapi_dsp_log Exit. Returning", error); - return error; -} - -/* Initializes default internal template */ -int elapi_set_default_tplt(unsigned base, ...) -{ - int error = EOK; - struct collection_item *tpl = NULL; - va_list args; - - TRACE_FLOW_STRING("elapi_set_default_tplt", "Entry"); - - if (global_dispatcher == NULL) { - error = elapi_init(NULL, NULL); - if (error) { - TRACE_ERROR_NUMBER("Failed to init ELAPI", error); - return error; - } - } - - /* Clean previous instance of the default template */ - elapi_destroy_event_tplt(global_dispatcher->default_tpl); - global_dispatcher->default_tpl = NULL; - - /* Process varible arguments */ - va_start(args, base); - - /* Create template out of base and args */ - error = elapi_create_event_tplt_with_vargs(&tpl, - base, - args); - va_end(args); - - if (error) { - TRACE_ERROR_NUMBER("Failed to create template. Error", error); - return error; - } - - global_dispatcher->default_tpl = tpl; - - TRACE_FLOW_STRING("elapi_set_default_tplt", "Exit"); - return error; -} - -/* There is one default template associated with the dispatcher */ -int elapi_get_default_tplt(struct collection_item **tpl) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_get_default_tplt", "Entry"); - - if ((global_dispatcher == NULL) || - (global_dispatcher->default_tpl == NULL)) { - TRACE_INFO_STRING("Default template does not exit", ""); - - error = elapi_set_default_tplt(E_BASE_DEFV1, E_EOARG); - if (error) { - TRACE_ERROR_NUMBER("Set default template returned error", error); - return error; - } - } - - *tpl = global_dispatcher->default_tpl; - TRACE_FLOW_NUMBER("elapi_get_default_tplt. Exit returning", error); - return error; -} - - - -/* Function to log raw key value pairs without creating an event */ -int elapi_dsp_msg(uint32_t target, - struct elapi_dispatcher *dispatcher, - struct collection_item *tpl, - ...) -{ - int error = EOK; - va_list args; - - TRACE_FLOW_STRING("elapi_dsp_msg", "Entry"); - - va_start(args, tpl); - - error = elapi_dsp_msg_with_vargs(target, dispatcher, tpl, args); - - va_end(args); - - TRACE_FLOW_STRING("elapi_dsp_msg.", "Exit"); - return error; -} - -/********** Advanced dispatcher managment functions **********/ - -/* Managing the sink collection */ -int elapi_alter_dispatcher(struct elapi_dispatcher *dispatcher, - const char *target, - const char *sink, - int action) -{ - - /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ - return EOK; -} - -/* Get sink list */ -char **elapi_get_sink_list(struct elapi_dispatcher *dispatcher, char *target) -{ - - /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ - return NULL; -} - -/* Free sink list */ -void elapi_free_sink_list(char **sink_list) -{ - - /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ - -} - -/* Get target list */ -char **elapi_get_target_list(struct elapi_dispatcher *dispatcher) -{ - - /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ - return NULL; -} - -/* Free target list */ -void elapi_free_target_list(char **target_list) -{ - - /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ - -} - - -/******************** High level interface ************************************/ -/* This interface is not thread safe but hides the dispatcher. */ - -/* This function will use internal default template */ -int elapi_create_simple_event(struct collection_item **event, ...) -{ - int error = EOK; - struct collection_item *evt = NULL; - va_list args; - struct collection_item *tpl = NULL; - - TRACE_FLOW_STRING("elapi_create_simple_event", "Entry"); - - /* Check storage */ - if (event == NULL ) { - TRACE_ERROR_STRING("Event storage must be provided", ""); - return EINVAL; - } - - *event = NULL; - - /* Get default template */ - error = elapi_get_default_tplt(&tpl); - if (error) { - TRACE_ERROR_NUMBER("Failed to get default template. Error", error); - return error; - } - - va_start(args, event); - - /* Create event */ - error = elapi_create_event_with_vargs(&evt, - tpl, - NULL, - 0, - args); - - va_end(args); - - if (error) { - TRACE_ERROR_NUMBER("Failed to create event using arg list. Error", error); - col_destroy_collection(evt); - return error; - } - - *event = evt; - - TRACE_FLOW_STRING("elapi_create_simple_event", "Exit"); - return error; -} - -/* Log key value pairs */ -int elapi_msg(uint32_t target, struct collection_item *tpl, ...) -{ - int error = EOK; - va_list args; - struct collection_item *use_tpl; - - TRACE_FLOW_STRING("elapi_msg", "Entry"); - - if (!tpl) { - /* Get default template */ - error = elapi_get_default_tplt(&use_tpl); - if (error) { - TRACE_ERROR_NUMBER("Failed to get default template. Error", error); - return error; - } - } - else use_tpl = tpl; - - va_start(args, tpl); - - error = elapi_dsp_msg_with_vargs(target, - global_dispatcher, - use_tpl, - args); - - va_end(args); - - TRACE_FLOW_NUMBER("elapi_msg Exit:", error); - return error; -} - -/* Log event */ -int elapi_log(uint32_t target, struct collection_item *event) -{ - int error; - - TRACE_FLOW_STRING("elapi_log", "Entry"); - - /* If dispatcher was not initialized do it automatically */ - if (global_dispatcher == NULL) { - error = elapi_init(NULL, NULL); - if (error) { - TRACE_ERROR_NUMBER("Failed to init ELAPI", error); - return error; - } - } - error = elapi_dsp_log(target, global_dispatcher, event); - - TRACE_FLOW_NUMBER("elapi_log Exit:", error); - return error; -} - -/* Get dispatcher if you want to add sink to a default dispatcher or do some advanced operations */ -struct elapi_dispatcher *elapi_get_dispatcher(void) -{ - TRACE_FLOW_STRING("elapi_get_dispatcher was called.", "Returning default dispatcher."); - return global_dispatcher; - -} - -/* Close ELAPI */ -void elapi_close(void) -{ - TRACE_FLOW_STRING("elapi_close","Entry"); - - /* Destroy global dispatcher */ - elapi_destroy_dispatcher(global_dispatcher); - global_dispatcher = NULL; - - TRACE_FLOW_STRING("elapi_close","Exit"); -} - -/* Function to initialize ELAPI library in the single threaded applications */ -int elapi_init(const char *appname, const char *config_path) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_init","Entry"); - - /* Clean the dispatcher if needed */ - elapi_close(); - - /* Create global dispatcher */ - error = elapi_create_dispatcher(&global_dispatcher, appname, config_path); - if (error) { - TRACE_ERROR_NUMBER("Failed to create default dispatcher. Error", error); - return error; - } - - /* Install a cleanup callback */ - if (!elapi_close_registered) { - if (atexit(elapi_close)) { - TRACE_ERROR_NUMBER("Failed to install cleanup callback. Error", ENOSYS); - /* NOTE: Could not find a better error for this case */ - return ENOSYS; - } - elapi_close_registered = 1; - } - - TRACE_FLOW_NUMBER("elapi_init Exit:",error); - return error; -} diff --git a/common/elapi/elapi_log.h b/common/elapi/elapi_log.h deleted file mode 100644 index 70841803..00000000 --- a/common/elapi/elapi_log.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - ELAPI - - Header file for 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/>. -*/ - -#ifndef ELAPI_LOG_H -#define ELAPI_LOG_H - -#include <stdint.h> - -#include "elapi_async.h" - -/* Default values for targets - - * these constants match values in the default configuration. - */ -#define E_TARGET_DEBUG 0x00000001 -#define E_TARGET_AUDIT 0x00000002 -#define E_TARGET_LOG 0x00000004 - - -/* Opaque dispatcher structure */ -struct elapi_dispatcher; - - -/******************** Low level thread safe interface ************************************/ -/* This interface should be used if application plans to control the dispatcher, - * implement its own sinks that can be added dynamically or implements it own routing function. - */ - -/********** Main functions of the interface **********/ -/* Structure that contains the pointer to functions - * that needed to be provided to enable async processing. - */ -struct elapi_async_ctx; - -/* Interface to create the async context */ -int elapi_create_asctx(struct elapi_async_ctx **ctx, - elapi_add_fd add_fd_cb, - elapi_rem_fd rem_fd_cb, - elapi_set_fd set_fd_cb, - void *ext_fd_data, - elapi_add_tm add_tm_cb, - elapi_rem_tm rem_tm_cb, - void *ext_tm_data); - -/* Function to free the async context */ -void elapi_destroy_asctx(struct elapi_async_ctx *ctx); - -/* Function to create a dispatcher */ -int elapi_create_dispatcher(struct elapi_dispatcher **dispatcher, /* Handle of the dispatcher will be stored in this variable */ - const char *appname, /* Application name. Passed to the sinks to do initialization */ - const char *config_path); /* See notes below in the elapi_init() function. */ - -/* A more advanced function to create a dispatcher */ -int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, /* Handle of the dispatcher will be stored in this variable */ - const char *appname, /* Application name. Passed to the sinks to do initialization */ - const char *config_path, /* See notes below in the elapi_init() function. */ - struct elapi_async_ctx *ctx); /* Async context. */ - -/* Function to clean memory associated with the dispatcher */ -void elapi_destroy_dispatcher(struct elapi_dispatcher *dispatcher); - -/* Function to log an event */ -int elapi_dsp_log(uint32_t target, - struct elapi_dispatcher *dispatcher, - struct collection_item *event); - -/* Function to log raw key value pairs without creating an event */ -int elapi_dsp_msg(uint32_t target, - struct elapi_dispatcher *dispatcher, - struct collection_item *tpl, - ...); - -/********** Advanced dispatcher management functions **********/ - -/* Managing the sink collection */ -int elapi_alter_dispatcher(struct elapi_dispatcher *dispatcher, /* Dispatcher */ - const char *target, /* Target to look for */ - const char *sink, /* Sink to change */ - int action); /* Action to perform for sink */ - -/* Get target list */ -char **elapi_get_target_list(struct elapi_dispatcher *dispatcher); - -/* Free target list */ -void elapi_free_target_list(char **target_list); - -/* Get sink list */ -char **elapi_get_sink_list(struct elapi_dispatcher *dispatcher, char *target); - -/* Free sink list */ -void elapi_free_sink_list(char **sink_list); - - -/******************** High level interface ************************************/ -/* This interface is not thread safe but convenient. It hides the dispatcher. */ - -/* Function to initialize ELAPI library in the single threaded applications */ -/* If config_path = NULL the configuration will be read from the standard locations: - * - First from the global configuration file "elapi.conf" located in the directory - * defined at the compile time by the ELAPI_DEFAULT_CONFIG_DIR constant. - * This file is assumed to contain common ELAPI configuration for this host; - * - Second from the file with name constructed from appname by appending to it - * suffix ".conf". The file will be looked in the directory pointed by - * ELAPI_DEFAULT_CONFIG_APP_DIR constant that is defined at compile time. - * The data from second file overwrites and complements the data from the first - * one. - * It is expected that applications will take advantage of the common - * central convention so config_path should be NULL in most cases. - * - * If config_path points to a file the function will try to read the file - * as if it is a configuration file. The appname is ignored in this case. - * If config_path points to a directory, the function will try to read - * configuration from the file with name constructed by appending suffix ".conf" - * to appname. The file will be looked up in that directory. - * If the config_path is neither file or directory the default values will be used - * to initialize dispatcher. - * - * In case appname is NULL a default value defined by build time constant - * ELAPI_DEFAULT_APP_NAME will be used. - */ -int elapi_init(const char *appname, const char *config_path); - -/* Log key value pairs */ -int elapi_msg(uint32_t target, - struct collection_item *tpl, ...); - -/* Log event */ -int elapi_log(uint32_t target, - struct collection_item *event); - -/* Corresponding wrapping macroses */ -#define ELAPI_EVT_DEBUG(event) elapi_log(E_TARGET_DEBUG, event) -#define ELAPI_EVT_LOG(event) elapi_log(E_TARGET_LOG, event) -#define ELAPI_EVT_AUDIT(event) elapi_log(E_TARGET_AUDIT, event) - -/* Get dispatcher if you want to do some advanced operations */ -struct elapi_dispatcher *elapi_get_dispatcher(void); - -/* Close audit */ -void elapi_close(void); - -#endif diff --git a/common/elapi/elapi_net.h b/common/elapi/elapi_net.h deleted file mode 100644 index c9f8af7e..00000000 --- a/common/elapi/elapi_net.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - ELAPI - - Header file for the ELAPI handling of netwok interfaces. - - 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/>. -*/ - -#ifndef ELAPI_NET_H -#define ELAPI_NET_H - -#include "config.h" - -#ifdef HAVE_GETIFADDRS -#include <ifaddrs.h> /* for getifaddrs() */ - -/* Macros then just wrap the getifaddrs() interface */ - -/* Type of the variable that stores the list */ -#define ELAPI_ADDRLIST struct ifaddrs * - -/* Type of the variable that stores the item */ -#define ELAPI_ADDRITEM struct ifaddrs * - -/* Function to build list of the interfaces */ -#define ELAPI_GET_ADDRLIST getifaddrs - -/* Macro to get first item from the list */ -#define ELAPI_GET_FIRST_ADDR_ITEM(list, item) \ - do { \ - item = list; \ - } while(0) - -/* Macro to get next item from the list */ -#define ELAPI_GET_NEXT_ADDR_ITEM(list, item) \ - do { \ - item = item->ifa_next; \ - } while(0) - - -/* Macro to get address */ -#define ELAPI_GET_ADDR(item, addr) \ - do { \ - addr = item->ifa_addr; \ - } while(0) - -/* Function to free the list */ -#define ELAPI_ADDR_LIST_CLEANUP freeifaddrs - -#else -/* Do everything using ioctl yourself... */ - -#include "elapi_ioctl.h" - -/* Type of the variable that stores the list */ -#define ELAPI_ADDRLIST struct ifconf - -/* Type of valiable that is used as a pointer */ -#define ELAPI_ADDRITEM struct ifreq * - -/* Function to build list of the interfaces */ -#define ELAPI_GET_ADDRLIST elapi_get_addrlist - -/* Macro to get first item from the list */ -#define ELAPI_GET_FIRST_ADDR_ITEM(list, item) \ - do { \ - item = (struct ifreq *)list.ifc_buf; \ - } while(0) - -/* Macro to get next item from the list */ -#define ELAPI_GET_NEXT_ADDR_ITEM(list, item) \ - do { \ - item = elapi_get_next_addr(&list, item); \ - } while(0) - - -/* Macro to get address */ -#define ELAPI_GET_ADDR(item, addr) \ - do { \ - addr = &(item->ifr_addr); \ - } while(0) - -/* Function to free the list */ -#define ELAPI_ADDR_LIST_CLEANUP(list) \ - do { \ - free(list.ifc_buf); \ - } while(0) - - -#endif /* HAVE_GETIFADDRS */ - -#endif diff --git a/common/elapi/elapi_priv.h b/common/elapi/elapi_priv.h deleted file mode 100644 index 15a03074..00000000 --- a/common/elapi/elapi_priv.h +++ /dev/null @@ -1,345 +0,0 @@ -/* - ELAPI - - Private header file continaing internal data for the ELAPI 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/>. -*/ - -#ifndef ELAPI_PRIV_H -#define ELAPI_PRIV_H - -#include <stdint.h> -#include <stdarg.h> - -#include "collection.h" -#include "elapi_basic.h" -#include "elapi_async.h" -#include "elapi_sink.h" - -/* Classes of the collections used by ELAPI internally */ -#define COL_CLASS_ELAPI_BASE 21000 -#define COL_CLASS_ELAPI_EVENT COL_CLASS_ELAPI_BASE + 0 -#define COL_CLASS_ELAPI_TEMPLATE COL_CLASS_ELAPI_BASE + 1 -#define COL_CLASS_ELAPI_SINK COL_CLASS_ELAPI_BASE + 2 -#define COL_CLASS_ELAPI_TARGET COL_CLASS_ELAPI_BASE + 3 -#define COL_CLASS_ELAPI_SINK_REF COL_CLASS_ELAPI_BASE + 4 -#define COL_CLASS_ELAPI_RES_ITEM COL_CLASS_ELAPI_BASE + 5 - -/* Names for the collections */ -#define E_TEMPLATE_NAME "tplt" -#define E_EVENT_NAME "event" - -/* Constants used in INI file and in - * the internal collection objects. - */ -#define ELAPI_DISPATCHER "dispatcher" -#define ELAPI_SINKS "sinks" -#define ELAPI_TARGETS "targets" -#define ELAPI_SINK_REFS "srefs" -#define ELAPI_TARGET_VALUE "value" -#define ELAPI_SINK_PROVIDER "provider" -#define ELAPI_SINK_REQUIRED "required" -#define ELAPI_SINK_ONERROR "onerror" -#define ELAPI_SINK_TIMEOUT "timeout" -#define ELAPI_SINK_SYNCH "synch" -#define ELAPI_RESOLVE_ITEM "res_item" - -/* Default timout before dispatcher tries to revive sink. - * The actual value is configurable on per sink basis - * so I do not see a value in making this a compile time - * option (at least at the moment). - */ -#define ELAPI_SINK_DEFAULT_TIMEOUT 60 - -/* Names of embedded providers */ -#define ELAPI_EMB_PRVDR_FILE "file" -#define ELAPI_EMB_PRVDR_SYSLOG "syslog" - -/* Numbers for embedded providers */ -#define ELAPI_EMB_PRVDR_FILENUM 0 -#define ELAPI_EMB_PRVDR_SYSLOGNUM 1 - -#define ELAPI_TARGET_ALL 0xFFFF /* 65k targets should be enough */ - -/* Possible values for onerror config parameter */ -#define ELAPI_ONERROR_REVIVE 0 -#define ELAPI_ONERROR_DISABLE 1 - -/* Structure that contains the pointer to functions - * that needed to be provided to enable async processing. - */ -struct elapi_async_ctx { - /* Callbacks related to file descriptor. */ - elapi_add_fd add_fd_cb; - elapi_rem_fd rem_fd_cb; - elapi_set_fd set_fd_cb; - /* File descriptor callback external data. */ - void *ext_fd_data; - /* Callbacks for timer */ - elapi_add_tm add_tm_cb; - elapi_rem_tm rem_tm_cb; - /* Timer's external data */ - void *ext_tm_data; -}; - -struct elapi_dispatcher { - /* Application name */ - char *appname; - /* List of target names and chars */ - char **targets; - /* Collection of targets */ - struct collection_item *target_list; - /* Counter of the targets */ - int target_counter; - /* Collection of sinks */ - struct collection_item *sink_list; - /* Configuration */ - struct collection_item *ini_config; - /* Items to resolve */ - struct collection_iterator *resolve_list; - /* Default event template */ - struct collection_item *default_tpl; - /* Async processing related data */ - struct elapi_async_ctx *async_ctx; -}; - - -/* This is a structure that holds the information - * about the target. - */ -struct elapi_tgt_ctx { - /* Value associted with the - * target in the config file. - */ - uint32_t target_value; - /* Collection of pointers to sink objects */ - struct collection_item *sink_ref_list; - /* FIXME - other things that belong here are: - * state of the chain - * reference to the current sink - * reference to the preferred sink - * etc. - */ -}; - -/* Structure that hols sink's error status */ -struct sink_status { - int suspended; - time_t lasttry; -}; - -/* Common configuration items for all sinks */ -struct elapi_sink_cfg { - char *provider; - uint32_t required; - uint32_t onerror; - uint32_t timeout; - uint32_t synch; - void *priv_ctx; - void *libhandle; - sink_cpb_fn ability; - struct sink_cpb cpb_cb; -}; - -/* The structure that describes the sink in the dispatcher */ -struct elapi_sink_ctx { - /* Input queue of a sink */ - struct collection_item *in_queue; - /* Pending list */ - struct collection_item *pending; - /* Sink's error status */ - struct sink_status status; - /* Synch/asynch mode */ - uint32_t async_mode; - /* Sink configuration data */ - struct elapi_sink_cfg sink_cfg; - /* Back pointer to the target context. - * This is needed for the cases - * when we detect that sink - * is failed and we need - * to fail over for the next one. - */ - struct elapi_tgt_ctx *tgt_ctx; - -}; - -/* A helper structure that holds data - * needed to resolve the event. - */ -struct elapi_resolve_data { - /* Reference to the message item inside event */ - struct collection_item *message; - /* Reference back to dispatcher */ - struct elapi_dispatcher *handle; - /* Time related data */ - time_t tm; - /* Structured UTC time */ - struct tm utc_time; - /* Structured local time */ - struct tm local_time; - /* Time offset */ - int offset; -}; - -/* Structure to pass data from logging function to targets */ -struct elapi_tgt_data { - struct collection_item *event; - struct elapi_dispatcher *handle; - uint32_t target_mask; -}; - - -/* Lookup structure for searching for providers */ -struct elapi_prvdr_lookup { - const char *name; - sink_cpb_fn ability; -}; - - -/* The structure to hold a command and a result of the command execution */ -struct elapi_get_sink { - int action; - int found; -}; - -/* Signature of the item resolution function */ -typedef int (*elapi_rslv_cb)(struct elapi_resolve_data *resolver, - struct collection_item *item, - int *skip); - -/* Structure to hold type-callback tuples */ -struct elapi_rslv_item_data { - int type; - elapi_rslv_cb resolve_cb; -}; - -/* Structure to hold name-data tuples */ -struct elapi_resolve_list { - const char *name; - struct elapi_rslv_item_data resolve_item; -}; - -/* Function to initialize resolution list */ -int elapi_init_resolve_list(struct collection_iterator **list); - -/* Function to create event using arg list */ -int elapi_create_event_with_vargs(struct collection_item **event, - struct collection_item *tpl, - struct collection_item *collection, - int mode, va_list args); - -/* Function to create event template using arg list */ -int elapi_create_event_tplt_with_vargs(struct collection_item **tpl, - unsigned base, - va_list args); - -/* Sink handler function */ -int elapi_sink_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop); - -/* Internal sink cleanup function */ -int elapi_sink_free_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop); - - - -/* Function to add a sink based on configuration */ -int elapi_sink_add(struct collection_item **sink_ref, - const char *sink, - struct elapi_dispatcher *handle); - -/* Function to create a sink */ -int elapi_sink_create(struct elapi_sink_ctx **sink_ctx, - const char *name, - struct collection_item *ini_config, - const char *appname); - -/* Destroy sink */ -void elapi_sink_destroy(struct elapi_sink_ctx *context); - -/* Send event into the sink */ -int elapi_sink_submit(struct elapi_sink_ctx *sink_ctx, - struct collection_item *event); - -/* Create target object */ -int elapi_tgt_create(struct elapi_tgt_ctx **context, - const char *target, - struct elapi_dispatcher *handle); - -/* Destroy target object */ -void elapi_tgt_destroy(struct elapi_tgt_ctx *context); - -/* Internal target cleanup function */ -int elapi_tgt_free_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop); - -/* Handler for logging through the targets */ -int elapi_tgt_cb(const char *target, - int target_len, - int type, - void *data, - int length, - void *passed_data, - int *stop); - -/* Submit event into the target */ -int elapi_tgt_submit(struct elapi_dispatcher *handle, - struct elapi_tgt_ctx *context, - struct collection_item *event); - -/* Create list of targets for a dispatcher */ -int elapi_tgt_mklist(struct elapi_dispatcher *handle); - -/* Create event context */ -int elapi_resolve_event(struct collection_item **final_event, - struct collection_item *event, - struct elapi_dispatcher *handle); - -/* Function to place the event items into a formatted string */ -int elapi_sprintf(struct elapi_data_out *out_data, - const char *format_str, - struct collection_item *event); - - -/* Send ELAPI config errors into a file */ -void elapi_dump_ini_err(struct collection_item *error_list); - -#ifdef ELAPI_VERBOSE -/* Print dispatcher internals for testing and debugging purposes */ -void elapi_print_dispatcher(struct elapi_dispatcher *handle); - -/* Print sink context details */ -void elapi_print_sink_ctx(struct elapi_sink_ctx *sink_context); -#else -#define elapi_print_dispatcher(arg) - -#endif - -#endif 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; -} diff --git a/common/elapi/elapi_sink.c b/common/elapi/elapi_sink.c deleted file mode 100644 index 0e2712f0..00000000 --- a/common/elapi/elapi_sink.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - ELAPI - - Module that contains functions that manipulate ELAPI sinks. - - 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 <sys/types.h> /* for stat() */ -#include <errno.h> /* for errors */ -#include <string.h> /* for memset() and other */ -#include <stdlib.h> /* for free() */ -#include <stdarg.h> /* for va_arg */ -#include <dlfcn.h> /* for dlopen() */ - -#include "elapi_priv.h" -#include "ini_config.h" -#include "file_provider.h" -#include "trace.h" -#include "config.h" - -/* NOTE: Add new provider here */ -struct elapi_prvdr_lookup providers[] = - {{ ELAPI_EMB_PRVDR_FILE, file_ability }, -/* { ELAPI_EMB_PRVDR_SYSLOG, syslog_ability } */ - { NULL, NULL }}; - - -/* This is a traverse callback for sink list */ -int elapi_sink_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - TRACE_FLOW_STRING("elapi_sink_cb", "Entry."); - - /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - TRACE_FLOW_STRING("elapi_sink_cb - skip header", "Exit."); - return EOK; - } - - printf("Sink: %s\n", sink); - - TRACE_FLOW_STRING("elapi_sink_cb", "Exit."); - return EOK; -} - -/* Destroy sink */ -void elapi_sink_destroy(struct elapi_sink_ctx *context) -{ - TRACE_FLOW_STRING("elapi_sink_destroy", "Entry."); - -#ifdef ELAPI_VERBOSE - /* FIXME: Can be removeed when the interface is stable */ - /* For testing purposes print the context we are trying to free */ - elapi_print_sink_ctx(context); -#endif - - if (context) { - TRACE_INFO_STRING("Context is not null.", "Destroying sink."); - /* FIXME: Do something about pending data if any */ - /* Assume for now that we do not care about pending data */ - - /* If the private data has been allocated and close callback is there - * call a callback to clean the data and free it. - */ - if (context->sink_cfg.priv_ctx) { - TRACE_INFO_STRING("Calling provider's close function.", ""); - /* Call close function of the provider */ - context->sink_cfg.cpb_cb.close_cb(&(context->sink_cfg.priv_ctx)); - } - - /* Now if the handle of the provider is set, offload the library instance */ - if (context->sink_cfg.libhandle) { - TRACE_INFO_STRING("Offloading shared library.", ""); - dlclose(context->sink_cfg.libhandle); - context->sink_cfg.libhandle = NULL; - } - - if (context->sink_cfg.provider) { - TRACE_INFO_STRING("Cleaning provider.", ""); - free(context->sink_cfg.provider); - context->sink_cfg.provider = NULL; - } - - TRACE_INFO_STRING("Freeing context", ""); - free(context); - } - - TRACE_FLOW_STRING("elapi_sink_destroy", "Exit."); -} - -/* Internal sink cleanup function */ -int elapi_sink_free_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - TRACE_FLOW_STRING("elapi_sink_free_cb", "Entry."); - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - TRACE_FLOW_STRING("elapi_sink_free_cb - skip header", "Exit."); - return EOK; - } - - TRACE_INFO_STRING("Cleaning Sink:", sink); - - elapi_sink_destroy(*((struct elapi_sink_ctx **)(data))); - - TRACE_FLOW_STRING("elapi_sink_free_cb", "Exit."); - return EOK; -} - -/* Function to read sink common configuration */ -static int elapi_read_sink_cfg(struct elapi_sink_cfg *sink_cfg, - const char *name, - struct collection_item *ini_config) -{ - int error = EOK; - struct collection_item *cfg_item = NULL; - const char *provider; - - TRACE_FLOW_STRING("elapi_read_sink_cfg", "Entry point"); - - /*********** Provider *************/ - - /* First check if this sink is properly configured and get its provider */ - error = get_config_item(name, - ELAPI_SINK_PROVIDER, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"provider\" attribute returned error", error); - return error; - } - - /* Do we have provider? */ - if (cfg_item == NULL) { - /* There is no provider - return error */ - TRACE_ERROR_STRING("Required key is missing in the configuration.", "Fatal Error!"); - return ENOENT; - } - - /* Get provider value */ - provider = get_const_string_config_value(cfg_item, &error); - if ((error) || (!provider) || (*provider == '\0')) { - TRACE_ERROR_STRING("Invalid \"provider\" value", "Fatal Error!"); - return EINVAL; - } - - /* Save provider inside configuration data */ - sink_cfg->provider = strdup(provider); - if (sink_cfg->provider == NULL) { - /* Failed to save the provider value */ - TRACE_ERROR_STRING("Failed to save \"provider\" value.", "Fatal Error!"); - return ENOMEM; - } - - /*********** Required *************/ - /* Next is "required" field */ - cfg_item = NULL; - error = get_config_item(name, - ELAPI_SINK_REQUIRED, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"required\" attribute returned error", error); - return error; - } - - /* Do we have "required"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"required\" attribute.", "Assume optional"); - sink_cfg->required = 0; - } - else { - sink_cfg->required = (uint32_t) get_bool_config_value(cfg_item, '\0', &error); - if (error) { - TRACE_ERROR_STRING("Invalid \"required\" value", "Fatal Error!"); - return EINVAL; - } - } - - /*********** Onerror *************/ - /* Next is "onerror" field */ - cfg_item = NULL; - error = get_config_item(name, - ELAPI_SINK_ONERROR, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"onerror\" attribute returned error", error); - return error; - } - - /* Do we have "required"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"onerror\" attribute.", "Assume retry (0)"); - sink_cfg->onerror = 0; - } - else { - sink_cfg->onerror = (uint32_t) get_unsigned_config_value(cfg_item, 1, 0, &error); - if (error) { - TRACE_ERROR_STRING("Invalid \"onerror\" value", "Fatal Error!"); - return EINVAL; - } - } - - /*********** Timeout *************/ - /* Next is "timeout" field */ - cfg_item = NULL; - error = get_config_item(name, - ELAPI_SINK_TIMEOUT, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"timeout\" attribute returned error", error); - return error; - } - - /* Do we have "required"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"timeout\" attribute.", "Assume default timeout"); - sink_cfg->timeout = ELAPI_SINK_DEFAULT_TIMEOUT; - } - else { - sink_cfg->timeout = (uint32_t) get_unsigned_config_value(cfg_item, - 1, - ELAPI_SINK_DEFAULT_TIMEOUT, - &error); - if (error) { - TRACE_ERROR_STRING("Invalid \"timeout\" value", "Fatal Error!"); - return EINVAL; - } - } - - /*********** Synch *************/ - /* Next is "synch" field */ - cfg_item = NULL; - error = get_config_item(name, - ELAPI_SINK_SYNCH, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"synch\" attribute returned error", error); - return error; - } - - /* Do we have "required"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"synch\" attribute.", "Assume retry (0)"); - sink_cfg->synch = 0; - } - else { - sink_cfg->synch = (uint32_t) get_bool_config_value(cfg_item, '\0', &error); - if (error) { - TRACE_ERROR_STRING("Invalid \"synch\" value", "Fatal Error!"); - return EINVAL; - } - } - - TRACE_FLOW_STRING("elapi_read_sink_cfg", "Exit"); - return error; -} - -/* Function to load external sink library */ -static int elapi_load_lib(void **libhandle, sink_cpb_fn *sink_fn, const char *name) -{ - char sink_lib_name[SINK_LIB_NAME_SIZE]; - sink_cpb_fn sink_symbol = NULL; - void *handle = NULL; - char *lib_error = NULL; - - TRACE_FLOW_STRING("elapi_load_lib", "Entry point"); - - if ((strlen(name) + sizeof(SINK_NAME_TEMPLATE)) >= SINK_LIB_NAME_SIZE) { - TRACE_ERROR_STRING("Provider string is too long:", name); - return EINVAL; - } - - /* I considered using snprintf here but prefer this way. - * Main reason is that snprintf will truncate - * the string and I would have to determine that after - * while in this implementation the copying - * would never even start if the buffer is not - * big enough. - */ - sprintf(sink_lib_name, SINK_NAME_TEMPLATE, name); - TRACE_INFO_STRING("Name of the library to try to load:", sink_lib_name); - - /* Load library */ - handle = dlopen(sink_lib_name, RTLD_LAZY); - if (!handle) { - TRACE_ERROR_STRING("Dlopen returned error", dlerror()); - return ELIBACC; - } - - /* Clear any existing error */ - dlerror(); - /* Get addres to the main entry point */ - sink_symbol = (sink_cpb_fn)(dlsym(handle, SINK_ENTRY_POINT)); - if ((lib_error = dlerror()) != NULL) { - TRACE_ERROR_STRING("Dlsym returned error", lib_error); - dlclose(handle); - return ELIBACC; - } - - *libhandle = handle; - *sink_fn = sink_symbol; - - TRACE_FLOW_STRING("elapi_load_lib", "Exit"); - return EOK; -} - -/* Function to load sink provider */ -int elapi_sink_loader(struct elapi_sink_cfg *sink_cfg) -{ - int error = EOK; - int num = 0; - - TRACE_FLOW_STRING("elapi_sink_loader", "Entry point"); - - while (providers[num].name) { - TRACE_INFO_STRING("Checking provider:", providers[num].name); - if (strcasecmp(providers[num].name, sink_cfg->provider) == 0) { - TRACE_INFO_STRING("Using provider:", providers[num].name); - sink_cfg->ability = providers[num].ability; - TRACE_FLOW_STRING("elapi_sink_loader", "Exit"); - return EOK; - } - num++; - } - - TRACE_INFO_NUMBER("Provider not found.", "Assume external."); - - /* It is an external provider */ - error = elapi_load_lib(&(sink_cfg->libhandle), &(sink_cfg->ability), sink_cfg->provider); - if (error) { - TRACE_ERROR_NUMBER("Failed to load library", error); - return error; - } - - TRACE_FLOW_STRING("elapi_sink_loader", "Exit"); - return error; -} - - -/* Function to load sink provider */ -int elapi_load_sink(struct elapi_sink_cfg *sink_cfg, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - TRACE_FLOW_STRING("elapi_load_sink", "Entry point"); - - /* Use sink loading wrapper */ - error = elapi_sink_loader(sink_cfg); - if (error) { - TRACE_ERROR_NUMBER("Failed to load sink", error); - return error; - } - - /* Call ability function to fill in the pointers */ - sink_cfg->ability(&(sink_cfg->cpb_cb)); - - /* Make sure the callbacks are initialized */ - if ((sink_cfg->cpb_cb.init_cb == NULL) || - (sink_cfg->cpb_cb.submit_cb == NULL) || - (sink_cfg->cpb_cb.close_cb == NULL)) { - TRACE_ERROR_NUMBER("One of the callbacks is missing", - "Bad provider!"); - return EINVAL; - } - - - /* Call init entry point */ - /* NOTE: it is the responsibility of the provider - * to enforce singleton in case provider can't - * be loaded more than once like syslog for example. - */ - error = sink_cfg->cpb_cb.init_cb(&(sink_cfg->priv_ctx), - name, - ini_config, - appname); - if (error) { - TRACE_ERROR_NUMBER("Failed to initalize sink", error); - return error; - } - - TRACE_FLOW_STRING("elapi_load_sink", "Exit"); - return error; - -} - -/* Function to create a sink */ -int elapi_sink_create(struct elapi_sink_ctx **sink_ctx, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - uint32_t required; - struct elapi_sink_ctx *sink_context = NULL; - - TRACE_FLOW_STRING("elapi_sink_create", "Entry point"); - - /* Allocate context */ - sink_context = (struct elapi_sink_ctx *)calloc(1, sizeof(struct elapi_sink_ctx)); - if (sink_context == NULL) { - TRACE_ERROR_NUMBER("Memory allocation failed. Error", ENOMEM); - return ENOMEM; - } - - /* Read common fields */ - error = elapi_read_sink_cfg(&(sink_context->sink_cfg), - name, ini_config); - if (error) { - TRACE_ERROR_NUMBER("Failed to read sink configuration", error); - elapi_sink_destroy(sink_context); - return error; - } - - TRACE_INFO_NUMBER("Address of init function", - sink_context->sink_cfg.cpb_cb.init_cb); - TRACE_INFO_NUMBER("Address of submit function", - sink_context->sink_cfg.cpb_cb.submit_cb); - TRACE_INFO_NUMBER("Address of close function", - sink_context->sink_cfg.cpb_cb.close_cb); - - /* Load sink */ - error = elapi_load_sink(&(sink_context->sink_cfg), - name, - ini_config, - appname); - if (error) { - TRACE_ERROR_NUMBER("Failed to load sink", error); - required = sink_context->sink_cfg.required; - elapi_sink_destroy(sink_context); - if (required) { - TRACE_ERROR_NUMBER("Sink is required so returning error", error); - return error; - } - else { - *sink_ctx = NULL; - TRACE_FLOW_STRING("Sink is not required so OK", "Exit"); - return EOK; - } - } - - /* We are done so return the context to the caller */ - *sink_ctx = sink_context; - - TRACE_FLOW_STRING("elapi_sink_create", "Exit"); - return error; -} - -/* Send event into the sink */ -int elapi_sink_submit(struct elapi_sink_ctx *sink_ctx, - struct collection_item *event) -{ - int error = EOK; - - TRACE_FLOW_STRING("elapi_sink_submit", "Entry"); - - /* FIXME: Manage the queue of the requests here. - * For now just call provider's submit function. - */ - error = sink_ctx->sink_cfg.cpb_cb.submit_cb(sink_ctx->sink_cfg.priv_ctx, - event); - - TRACE_FLOW_STRING("elapi_sink_submit", "Exit"); - return error; -} diff --git a/common/elapi/elapi_sink.h b/common/elapi/elapi_sink.h deleted file mode 100644 index 03e681a5..00000000 --- a/common/elapi/elapi_sink.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - ELAPI - - Common sink interface header. - - 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/>. -*/ - -#ifndef ELAPI_SINK_H -#define ELAPI_SINK_H - -#include <time.h> -#include "collection.h" - -#define ELAPI_SINK_OK 0 /* Sink can be used for logging */ -#define ELAPI_SINK_SUSPENDED 1 /* Sink is temporary disabled due to recoverable error */ -#define ELAPI_SINK_DISABLED 2 /* Sink is explicitely disabled by the application */ -#define ELAPI_SINK_PULSE 3 /* Sink is disabled for this one event */ - -#define SINK_LIB_NAME_SIZE 100 -#define SINK_ENTRY_POINT "get_sink_info" -#define SINK_NAME_TEMPLATE "libelapi_sink_%s.so" - -/* Log facility callbacks */ -/* FIXME - the signatures need to take into the account async processing */ -typedef int (*init_fn)(void **priv_ctx, - const char *name, - struct collection_item *ini_config, - const char *appname); - -typedef int (*submit_fn)(void *priv_ctx, struct collection_item *event); -typedef void (*close_fn)(void **priv_ctx); - -struct sink_cpb { - init_fn init_cb; - submit_fn submit_cb; - close_fn close_cb; -}; - -/* The only open function the sink can expose */ -typedef void (*sink_cpb_fn)(struct sink_cpb *sink_cpb_block); - - -/* Standard capability function */ -void get_sink_info(struct sink_cpb *cpb_block); - -#endif diff --git a/common/elapi/elapi_subst.c b/common/elapi/elapi_subst.c deleted file mode 100644 index da507aa5..00000000 --- a/common/elapi/elapi_subst.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - ELAPI - - Module contains functions related to format substitution - - 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 <string.h> -#include <stdio.h> -#include "elapi_priv.h" -#include "trace.h" -#include "config.h" - -/* Reasonable size for one event */ -/* FIXME: may be it would make sense to make it configurable ? */ -#define ELAPI_SUBST_BLOCK 256 - -/* Calculate the potential size of the item */ -static unsigned elapi_get_item_len(int type, int raw_len) -{ - int serialized_len = 0; - - TRACE_FLOW_STRING("elapi_get_item_len", "Entry point"); - - switch (type) { - case COL_TYPE_INTEGER: - case COL_TYPE_UNSIGNED: - case COL_TYPE_LONG: - case COL_TYPE_ULONG: - serialized_len = MAX_LONG_STRING_LEN; - break; - - case COL_TYPE_STRING: - serialized_len = raw_len; - break; - - case COL_TYPE_BINARY: - serialized_len = raw_len * 2; - break; - - case COL_TYPE_DOUBLE: - serialized_len = MAX_DOUBLE_STRING_LEN; - break; - - case COL_TYPE_BOOL: - serialized_len = MAX_BOOL_STRING_LEN; - break; - - default: - serialized_len = 0; - break; - } - - TRACE_FLOW_STRING("elapi_get_item_len", "Exit point"); - return (uint32_t)serialized_len; -} - - -/* Function to serialize one item */ -static int elapi_sprintf_item(struct elapi_data_out *out_data, - struct collection_item *item) -{ - int error = EOK; - uint32_t projected_len; - uint32_t used_len; - uint32_t item_len; - void *data; - int type; - int i; - - TRACE_FLOW_STRING("elapi_sprintf_item", "Entry"); - - /* Get projected length of the item */ - item_len = col_get_item_length(item); - type = col_get_item_type(item); - projected_len = elapi_get_item_len(type, item_len); - - TRACE_INFO_NUMBER("Expected data length: ", projected_len); - - /* Make sure we have enough space */ - if (out_data->buffer == NULL) { - TRACE_INFO_STRING("First time use.", ""); - /* Add null terminating zero */ - projected_len++; - } - - /* Grow buffer if needed */ - error = elapi_grow_data(out_data, - projected_len, - ELAPI_SUBST_BLOCK); - if (error) { - TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", error); - return error; - } - - data = col_get_item_data(item); - - /* Add the value */ - switch (type) { - case COL_TYPE_STRING: - - /* Item's length includes trailing 0 for data items */ - used_len = item_len - 1; - memcpy(&out_data->buffer[out_data->length], - (const char *)(data), - used_len); - out_data->buffer[out_data->length + used_len] = '\0'; - break; - - case COL_TYPE_BINARY: - - for (i = 0; i < item_len; i++) { - sprintf((char *)&out_data->buffer[out_data->length + i * 2], - "%02X", (unsigned int)(((const unsigned char *)(data))[i])); - } - used_len = item_len * 2; - /* We need it here for the case item_len = 0 */ - out_data->buffer[out_data->length + used_len] = '\0'; - break; - - case COL_TYPE_INTEGER: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%d", *((const int *)(data))); - break; - - case COL_TYPE_UNSIGNED: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%u", *((const unsigned int *)(data))); - break; - - case COL_TYPE_LONG: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%ld", *((const long *)(data))); - break; - - case COL_TYPE_ULONG: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%lu", *((const unsigned long *)(data))); - break; - - case COL_TYPE_DOUBLE: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%.4f", *((const double *)(data))); - break; - - case COL_TYPE_BOOL: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%s", - (*((const unsigned char *)(data))) ? "true" : "false"); - break; - - default: - out_data->buffer[out_data->length] = '\0'; - used_len = 0; - break; - } - - /* Adjust length */ - out_data->length += used_len; - - TRACE_INFO_STRING("Data: ", (char *)out_data->buffer); - - TRACE_FLOW_STRING("elapi_sprintf_item", "Exit"); - return error; - -} - -/* Lookup item hoping that items in message are somewhat ordered. - * If there is some ordering we will save on performance. - * If not we will not loos against a standard lookup. - */ -static struct collection_item *elapi_lookup_item(const char *start, - int length, - struct collection_iterator *iterator) -{ - int error = EOK; - struct collection_item *found = NULL; - const char *property; - int property_len; - uint64_t hash; - - TRACE_FLOW_STRING("elapi_lookup_item", "Entry"); - - /* Prepare hash */ - hash = col_make_hash(start, length, NULL); - - /* 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(iterator, - &found); - if (error) { - TRACE_ERROR_NUMBER("Failed to iterate collection", error); - return NULL; - } - - /* Are we done ? This means we looped and did not find - * the item. */ - if (found == NULL) break; - - property = col_get_item_property(found, &property_len); - - /* Compare item and the property */ - if ((hash == col_get_item_hash(found)) && - (length == property_len) && - (strncasecmp(start, property, length) == 0)) { - /* This is our item !!! */ - /* Pin down the iterator here */ - col_pin_iterator(iterator); - - /* Break out of loop */ - break; - } - } - - TRACE_FLOW_STRING("elapi_lookup_item", "Exit"); - return found; -} - - -/* Function to parse format string */ -static const char *elapi_parse_format(const char *start, - int *length, - struct collection_item **item, - struct collection_iterator *iterator) -{ - const char *runner; - const char *bracket; - const char *name_start; - - TRACE_FLOW_STRING("elapi_parse_format", "Entry"); - if ((start == NULL) || (*start == '\0')) { - TRACE_FLOW_STRING("String is empty", "Return"); - return NULL; - } - - runner = start; - - while (1) { - /* First check for end of the string */ - if (*runner == '\0') { - TRACE_FLOW_STRING("Found last token", start); - *length = runner - start; - return runner; - } - - /* Is it the beginning of the field substitution? */ - if (*runner == '%') { - /* Check for bracket */ - if (*(runner + 1) == '(') { - /* Search for closing one */ - name_start = runner + 2; - bracket = name_start; - while (1) { - /* Check for the end */ - if (*bracket == '\0') { - TRACE_FLOW_STRING("No closing bracket", start); - *length = bracket - start; - return bracket; - } - /* Did we find closing backet? */ - if (*bracket == ')') { - TRACE_FLOW_STRING("Bracket is found: ", name_start); - /* There might be specific format specifiers */ - if (*name_start == '!') { - /* Force rewind of the - * iterator */ - col_rewind_iterator(iterator); - name_start++; - } - - /* FIXME: Add other specifiers here... - * Specifier that can be supported in future - * might expand multi value property - * to a list of values separated by - * provided symbol. - */ - - *item = elapi_lookup_item(name_start, - bracket - name_start, - iterator); - bracket++; - if (*item == NULL) { - /* The item is not known (or error) */ - TRACE_FLOW_STRING("No item in event", name_start); - *length = bracket - start; - return bracket; - } - - /* Item is found */ - TRACE_FLOW_STRING("Item found: ", name_start); - *length = runner - start; - return bracket; - } - bracket++; - } - } - } - runner++; - } - /* This point is unreachable */ -} - -/* Function to place the event items into the formatted string */ -int elapi_sprintf(struct elapi_data_out *out_data, - const char *format_str, - struct collection_item *event) -{ - const char *start; - int length; - struct collection_item *item; - struct collection_iterator *iterator = NULL; - const char *result; - int error; - - TRACE_FLOW_STRING("elapi_sprintf", "Entry"); - - /* Create iterator - by thus time cevent is resolved and should - * be a flattened collection. At least this is the assumption. - */ - error = col_bind_iterator(&iterator, event, COL_TRAVERSE_IGNORE); - if (error) { - TRACE_ERROR_NUMBER("Failed to bind iterator", error); - return error; - } - - start = format_str; - - while(1) { - - item = NULL; - length = 0; - - /* Parse format definition */ - result = elapi_parse_format(start, &length, &item, iterator); - if (result == NULL) { - TRACE_INFO_STRING("Done parsing string", ""); - break; - } - - /* Apply parsed data */ - if (length > 0) { - error = elapi_grow_data(out_data, - length + 1, - ELAPI_SUBST_BLOCK); - if (error) { - TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", error); - col_unbind_iterator(iterator); - return error; - } - - memcpy(&out_data->buffer[out_data->length], - (const char *)(start), - length); - - out_data->length += length; - /* We asked for this one extra byte above */ - out_data->buffer[out_data->length] = '\0'; - } - - if (item != NULL) { - TRACE_INFO_NUMBER("Need to output item", error); - error = elapi_sprintf_item(out_data, item); - if (error) { - TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", error); - col_unbind_iterator(iterator); - return error; - } - } - - start = result; - } - - col_unbind_iterator(iterator); - - TRACE_FLOW_STRING("elapi_sprintf", "Exit"); - return error; -} diff --git a/common/elapi/elapi_test/Makefile.am b/common/elapi/elapi_test/Makefile.am deleted file mode 100644 index 8a24b9f0..00000000 --- a/common/elapi/elapi_test/Makefile.am +++ /dev/null @@ -1,63 +0,0 @@ -TRACE_LEVEL=@TRACE_VAR@ - -topdir=$(srcdir)/../.. - -AM_CFLAGS = -DELAPI_DEFAULT_CONFIG_DIR=\"$(srcdir)\" \ - -DELAPI_DEFAULT_CONFIG_APP_DIR=\"$(srcdir)\" \ - -DELAPI_DEFAULT_APP_NAME=\"elapi_ut\" \ - -DELAPI_DEFAULT_APP_NAME_SIZE=127 - -if HAVE_GCC - AM_CFLAGS += \ - -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \ - -Wcast-align -Wwrite-strings -endif - -AM_CPPFLAGS = -I$(topdir) -I$(topdir)/ini -I$(topdir)/trace -I$(topdir)/collection -I$(topdir)/elapi \ - -I$(topdir)/elapi/providers/file $(TRACE_LEVEL) - -ACLOCAL_AMFLAGS = -I m4 - -dist_noinst_DATA = m4 \ - elapi_ut.conf - -# Build library -noinst_LTLIBRARIES = libelapi_test.la - -libelapi_test_la_SOURCES = \ - ../elapi_event.c \ - ../elapi_log.c \ - ../elapi_internal.c \ - ../elapi_sink.c \ - ../elapi_basic.c \ - ../elapi_basic.h \ - ../elapi_resolve.c \ - ../elapi_async.c \ - ../elapi_subst.c \ - ../elapi_ioctl.c \ - ../elapi_event.h \ - ../elapi_priv.h \ - ../elapi_sink.h \ - ../elapi_log.h \ - ../elapi_async.h \ - ../elapi_ioctl.h \ - ../elapi_net.h \ - ../elapi_fd.h \ - ../elapi_tm.h \ - ../elapi_defines.h \ - ../elapi.h \ - ../providers/file/file_provider.c \ - ../providers/file/file_provider.h \ - ../providers/file/file_util.c \ - ../providers/file/file_util.h \ - ../providers/file/file_fmt_csv.c \ - ../providers/file/file_fmt_csv.h - -# Build unit test -check_PROGRAMS = elapi_ut -elapi_ut_SOURCES = elapi_ut.c -elapi_ut_LDADD = libelapi_test.la ../../ini/libini_config.la ../../collection/libcollection.la -ldl - -TESTS = elapi_ut - -tests: all $(check_PROGRAMS) diff --git a/common/elapi/elapi_test/configure.ac b/common/elapi/elapi_test/configure.ac deleted file mode 100644 index 44524e70..00000000 --- a/common/elapi/elapi_test/configure.ac +++ /dev/null @@ -1,32 +0,0 @@ -AC_INIT([elapi],[0.0.1],[sssd-devel@lists.fedorahosted.org]) -AC_CONFIG_SRCDIR([elapi_ut.c]) -AC_CONFIG_AUX_DIR([build]) -AM_INIT_AUTOMAKE([-Wall -Werror foreign]) -AC_PROG_CC -AC_PROG_LIBTOOL -AC_CONFIG_MACRO_DIR([m4]) -AC_PROG_INSTALL - -AM_CONDITIONAL([HAVE_GCC], [test "$ac_cv_prog_gcc" = yes]) - -m4_pattern_allow([AM_SILENT_RULES]) -AM_SILENT_RULES - -AC_CONFIG_HEADERS([config.h]) - -# Enable trace build -AC_ARG_ENABLE([trace], - [AS_HELP_STRING([--enable-trace[=LEVEL]],[build with low level tracing enabled])], - [trace_level="$enableval"], - [trace_level="0"]) -AS_IF([test ["$trace_level" -gt "0"] -a ["$trace_level" -lt "8"] ],[AC_SUBST([TRACE_VAR],["-DTRACE_LEVEL=$trace_level"])]) - -# Enable trace build -AC_ARG_ENABLE([verbose], - [AS_HELP_STRING([--enable-verbose],[build with verbose output])], - [AC_DEFINE([ELAPI_VERBOSE],[],[add verbose output])],[]) - -m4_include(../def_macros.m4) - -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT diff --git a/common/elapi/elapi_test/elapi_ut.c b/common/elapi/elapi_test/elapi_ut.c deleted file mode 100644 index 49fe1a26..00000000 --- a/common/elapi/elapi_test/elapi_ut.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - ELAPI - - Unit test for the ELAPI event 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/>. -*/ - -#include <stdio.h> -#include <stdarg.h> -#define TRACE_HOME -#include "trace.h" -#include "elapi.h" -#include "collection_tools.h" - -/* THIS IS A PRIVATE HEADER - included for debugging purposes only! */ -#include "elapi_priv.h" - -#define APPNAME "elapi_ut" -#define ELAPI_CONFIG_FILE "elapi_ut.conf" - -typedef int (*test_fn)(void); - -int elapi_init_test(void) -{ - int error = 0; - - printf("elapi_init test START:\n"); - - error = elapi_init(APPNAME, "./"ELAPI_CONFIG_FILE); - if (error) { - printf("elapi_init failed: %d\n", error); - return error; - } - - elapi_close(); - - printf("elapi_init test success!\n"); - return 0; -} - -int elapi_get_default_tplt_test(void) -{ - struct collection_item *tpl; - int error = 0; - - printf("elapi_get_default_tplt_test test START:\n"); - - error = elapi_get_default_tplt(&tpl); - if (error) { - printf("elapi_get_default_tplt failed: %d\n", error); - return error; - } - - printf("elapi_get_default_tplt test success!\n"); - return 0; -} - -int simple_event_test(void) -{ - int error = 0; - struct collection_item *event; - char bin[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - - printf("Simple test START:\n"); - - error = elapi_set_default_tplt( - E_BASE_DEFV1 | E_BASE_HOSTEXT /* FIXME Ticket #207 */, - "%n( bin )", bin, 8, - " %sb( logical1 )", "false", - "%sb( logical2 )", "YES", - " %db(logical3)", 1, - "%d(int_number),", -200, - "%u(unsigned_number)", 300, - "%ld(long_number)", -1234567, - "%lu(long_unsigned_number)", 123456789, - "%s(just_string)", "string", - "%*s(sub_string)", "truncated string", 10, /* Expect word truncated */ - "%e(double_number)", 3.141592 * 3, - "simple", "value", - "-" E_UTCTIME, /* Remove UTCTIME from the list */ - E_MESSAGE, - "%(stamp), %s(sub_string), %(int_number), %(unsigned_number), %(long_unsigned_number), %(bin), %e(double_number)", - E_EOARG); - - if (error) { - printf("Failed to set default template! %d\n", error); - return error; - } - - error = elapi_create_simple_event( - &event, - " %db(foo_logical)", 0, - "%d(foo_int_number),", -2000, - "%u(foo_unsigned_number)", 3000, - "%ld(foo_long_number)", -7654321, - E_EOARG); - - if (error) { - printf("Failed to create simple event! %d\n", error); - return error; - } - - error = ELAPI_EVT_DEBUG(event); - if (error) { - printf("Failed to log event to debug ! %d\n", error); - elapi_destroy_event(event); - return error; - } - - error = ELAPI_EVT_LOG(event); - if (error) { - printf("Failed to log event to log ! %d\n", error); - elapi_destroy_event(event); - return error; - } - - error = ELAPI_EVT_AUDIT(event); - - if (error) { - printf("Failed to log event to audit ! %d\n", error); - elapi_destroy_event(event); - return error; - } - - elapi_destroy_event(event); - - error = elapi_msg(E_TARGET_DEBUG, NULL, "a", "b", "c", "d", E_EOARG); - if (error) { - printf("Failed to log \"debug\" event! %d\n", error); - return error; - } - - error = elapi_msg(E_TARGET_LOG, NULL, "a", "b", "c", "d", E_EOARG); - if (error) { - printf("Failed to log \"log\" event! %d\n", error); - return error; - } - - error = elapi_msg(E_TARGET_AUDIT, NULL, "a", "b", "c", "d", E_EOARG); - if (error) { - printf("Failed to log \"audit\" event! %d\n", error); - return error; - } - - /* Internal function to print dispatcher guts */ - elapi_print_dispatcher(elapi_get_dispatcher()); - - printf("Simple test success!\n"); - - return error; -} - -int complex_event_test(void) -{ - int error = 0; - struct collection_item *tpl = NULL; - struct collection_item *event = NULL, *event_copy = NULL; - char bin[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - struct collection_item *col = NULL; - struct elapi_dispatcher *dispatcher = NULL; - - printf("Complex test START:\n"); - - error = elapi_create_event_tplt( - &tpl, - E_BASE_DEFV1 | E_BASE_HOSTEXT, - "%lu(long_unsigned_number)", 123456789, - "%s(just_string)", "string", - "%*s(sub_string)", "truncated string", 10, /* Expect word truncated */ - "%e(double_number)", 3.141592 * 3, - "simple", "value", - "-" E_UTCTIME, /* Remove UTCTIME from the list */ - E_MESSAGE, - "%(stamp), %s(sub_string), %(int_number), %(unsigned_number), %(long_unsigned_number), %(bin), %e(double_number)", - E_EOARG); - - if (error) { - printf("Failed to set create template %d\n", error); - return error; - } - - error = elapi_create_event( - &event, - tpl, - NULL, - 0, - " %db(evt_logical)", 0, - "%d(evt_int_number),", -2000, - "%u(evt_unsigned_number)", 3000, - "%ld(evt_long_number)", -7654321, - E_EOARG); - - if (error) { - printf("Failed to set create template %d\n", error); - elapi_destroy_event_tplt(tpl); - return error; - } - - col_debug_collection(tpl, COL_TRAVERSE_DEFAULT); - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - - error = elapi_log(E_TARGET_DEBUG, event); - - elapi_destroy_event(event); - - if (error) { - printf("Failed to log event! %d\n", error); - return error; - } - - - elapi_destroy_event_tplt(tpl); - - error = elapi_create_event_tplt( - &tpl, - E_BASE_DEFV1 | E_BASE_HOSTEXT, - "%n( bin )", bin, 8, - " %sb( logical1 )", "false", - "%sb( logical2 )", "YES", - " %db(logical3)", 1, - "%d(int_number),", -200, - "%u(unsigned_number)", 300, - "%ld(long_number)", -1234567, - "%lu(long_unsigned)", -1234567, - E_MESSAGE, - "%(stamp), %(sub_string), %(int_number), %(unsigned_number), %(long_unsigned_number), %(bin), %(double_number)", - E_EOARG); - - if (error) { - printf("Failed to set create template %d\n", error); - return error; - } - - if ((error = col_create_collection(&col, "test", 0)) || - /* We are forcing overwrite with different type */ - (error = col_add_int_property(col, NULL, "unsigned_number", 1)) || - (error = col_add_long_property(col, NULL, "bin", 100000000L))) { - elapi_destroy_event_tplt(tpl); - printf("Failed to add property. Error %d\n", error); - return error; - } - - error = elapi_create_event( - &event, - tpl, - col, - COL_ADD_MODE_FLAT, - E_MESSAGE, - "%(stamp) a good message", - "-int_number", - E_EOARG); - - if (error) { - printf("Failed to set create template %d\n", error); - elapi_destroy_event_tplt(tpl); - col_destroy_collection(col); - return error; - } - - col_destroy_collection(col); - - col_debug_collection(tpl, COL_TRAVERSE_DEFAULT); - - printf("\nPRINTING EVENT\n\n"); - printf("\nPRINTING EVENT, removed message added bin\n\n"); - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - - - if ((error = col_create_collection(&col, "test", 0)) || - /* We are forsing overwrite with different type */ - (error = col_add_int_property(col, NULL, "zzz", 1)) || - (error = col_add_long_property(col, NULL, "zzz2", 100000000L))) { - elapi_destroy_event_tplt(tpl); - printf("Failed to add property. Error %d\n", error); - elapi_destroy_event(event); - return error; - } - - error = elapi_modify_event( - event, - col, - COL_ADD_MODE_REFERENCE, - "-"E_MESSAGE, - "bin", "bin-string", - E_EOARG); - - if (error) { - printf("Failed to set create template %d\n", error); - elapi_destroy_event(event); - elapi_destroy_event_tplt(tpl); - col_destroy_collection(col); - return error; - } - - printf("\nPRINTING EVENT, removed message, added bin,\n" - "added test collection with zzz & zzz2\n\n"); - - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - col_destroy_collection(col); - - if ((error = col_create_collection(&col, "flat", 0)) || - /* We are forsing overwrite with different type */ - (error = col_add_int_property(col, NULL, "zzz", 1)) || - (error = col_add_long_property(col, NULL, "zzz2", 100000000L))) { - elapi_destroy_event_tplt(tpl); - printf("Failed to add property. Error %d\n", error); - elapi_destroy_event(event); - return error; - } - - error = elapi_modify_event( - event, - col, - COL_ADD_MODE_FLATDOT, - E_EOARG); - - if (error) { - printf("Failed to set create template %d\n", error); - elapi_destroy_event(event); - elapi_destroy_event_tplt(tpl); - col_destroy_collection(col); - return error; - } - - printf("\nPRINTING EVENT, added flat collection with zzz & zzz2\n\n"); - - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - col_destroy_collection(col); - - error = elapi_copy_event(&event_copy, event); - if (error) { - printf("Failed to set create template %d\n", error); - elapi_destroy_event(event); - elapi_destroy_event_tplt(tpl); - return error; - } - - error = elapi_create_dispatcher(&dispatcher, "elapi_ut", "./sdfdsdf"); - if (error) { - elapi_destroy_event(event); - elapi_destroy_event(event_copy); - elapi_destroy_event_tplt(tpl); - printf("Failed to create dispatcher %d\n", error); - return error; - } - - error = elapi_dsp_log(E_TARGET_DEBUG, dispatcher, event); - - elapi_destroy_event(event); - - if (error) { - elapi_destroy_event(event_copy); - elapi_destroy_event_tplt(tpl); - printf("Failed to log event! %d\n", error); - return error; - } - - error = elapi_dsp_log(E_TARGET_DEBUG, dispatcher, event_copy); - - elapi_destroy_event(event_copy); - - if (error) { - elapi_destroy_event_tplt(tpl); - printf("Failed to log event! %d\n", error); - return error; - } - - error = elapi_dsp_msg(E_TARGET_DEBUG, dispatcher, tpl, "a", "b", "c", "d", E_EOARG); - if (error) { - elapi_destroy_event_tplt(tpl); - printf("Failed to log event! %d\n", error); - return error; - } - - error = elapi_dsp_msg(E_TARGET_DEBUG, dispatcher, NULL, "a", "b", "c", "d", E_EOARG); - if (error) { - elapi_destroy_event_tplt(tpl); - printf("Failed to log event! %d\n", error); - return error; - } - - error = elapi_dsp_msg(E_TARGET_DEBUG, - dispatcher, - tpl, - E_MESSAGE, - "date = %(R_stamp__), pid = %(__pid__), " - "hostname = %(__host__), %(__halias__), " - "ip = %(__ip__), [%(__iplist__); %(!__iplist__); %(__iplist__)]" , - E_EOARG); - if (error) { - elapi_destroy_event_tplt(tpl); - printf("Failed to log event! %d\n", error); - return error; - } - - error = elapi_dsp_msg(E_TARGET_DEBUG, - dispatcher, - tpl, - E_MESSAGE, - "date = %(R_stamp__), pid = %(__pid__), " - "hostname = %(__host__), %(__halias__), " - "ip = %(__ip__), [%(__iplist__); %(__iplist__); %(__iplist__)]" , - E_EOARG); - if (error) { - elapi_destroy_event_tplt(tpl); - printf("Failed to log event! %d\n", error); - return error; - } - - elapi_destroy_event_tplt(tpl); - - elapi_print_dispatcher(dispatcher); - - elapi_destroy_dispatcher(dispatcher); - - return error; -} - - -int template_test(void) -{ - int error = 0; - struct collection_item *event; - - printf("Template test START:\n"); - - error = elapi_set_default_tplt( - E_HAVE_HOSTNAME, - E_EOARG); - - if (error) { - printf("Failed to set default template! %d\n", error); - return error; - } - - error = elapi_create_simple_event( - &event, - E_EOARG); - - if (error) { - printf("Failed to create simple event! %d\n", error); - return error; - } - - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - elapi_destroy_event(event); - - error = elapi_set_default_tplt( - E_HAVE_HOSTALIAS, - E_EOARG); - - if (error) { - printf("Failed to set default template! %d\n", error); - return error; - } - - error = elapi_create_simple_event( - &event, - E_EOARG); - - if (error) { - printf("Failed to create simple event! %d\n", error); - return error; - } - - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - elapi_destroy_event(event); - - error = elapi_set_default_tplt( - E_HAVE_HOSTIP, - E_EOARG); - - if (error) { - printf("Failed to set default template! %d\n", error); - return error; - } - - error = elapi_create_simple_event( - &event, - E_EOARG); - - if (error) { - printf("Failed to create simple event! %d\n", error); - return error; - } - - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - elapi_destroy_event(event); - - error = elapi_set_default_tplt( - E_HAVE_HOSTIPS, - E_EOARG); - - if (error) { - printf("Failed to set default template! %d\n", error); - return error; - } - - error = elapi_create_simple_event( - &event, - E_EOARG); - - if (error) { - printf("Failed to create simple event! %d\n", error); - return error; - } - - col_debug_collection(event, COL_TRAVERSE_DEFAULT); - elapi_destroy_event(event); - - return EOK; -} - - -/* Main function of the unit test */ - -int main(int argc, char *argv[]) -{ - int error = 0; - test_fn tests[] = { elapi_init_test, - elapi_get_default_tplt_test, - simple_event_test, - complex_event_test, - template_test, - NULL }; - test_fn t; - int i = 0; - - printf("Start\n"); - - while ((t = tests[i++])) { - error = t(); - if (error) { - printf("Failed!\n"); - return error; - } - } - - printf("Success!\n"); - return 0; -} diff --git a/common/elapi/elapi_test/elapi_ut.conf b/common/elapi/elapi_test/elapi_ut.conf deleted file mode 100644 index a42045a2..00000000 --- a/common/elapi/elapi_test/elapi_ut.conf +++ /dev/null @@ -1,218 +0,0 @@ -; This is a sample configuration file for ELAPI - -; The dispatcher section defines general configuration -; for the ELAPI. It has following configuration parameters: -; -; targets - (required) -; Defines possible logical destinations where message can be sent. -; It is one of the arguments of the calling interface. It is numeric. -; It is done this way for performance reasons so it is faster to compare. -; But in the configuration it is easier to deal with targets as strings. -; To overcome this issue each target is assigned a number in the INI file. -; The ELAPI convention is to have three default targets: -; "debug", "audit" and "log" but application developers can add others as needed. -; The default value for debug target is 1, for audit 2 and log is 4. -; Changing the value defined for debug to be 7 ( logical OR of 1, 2 and 4) -; will result in all messages sent into debug log. -; This might be convenient during troubleshooting and would allow seeing all -; events emitted by the application in one place. -; If you want the event to be sent into two targets at the same time -; add a target with different name but same value. -; For example if the log events need to go to local and remote files -; in parallel you would create another target: logremote -; and give it same value as log (which by convention is 4) - - - -[dispatcher] -targets=debug, audit, log - -; Inside section for each target the following parameters can be defined: -; -; value - (optional) -; Stores the value associated with this target. -; If the bit-wise AND of this value and the value provided by caller -; of the interface is greater than 0 the event is logged into the -; target destination. If omitted all events are sent to this target. -; sinks - (required) -; Defines the list of the sink names that need to be loaded -; each will have its own section. -; Only one of the sinks is active - first in the list. -; The list contains sinks in the fail over order. -; - -[debug] -value = 1 -sinks = debugfile, screen - -[audit] -value = 2 -sinks = auditfile, syslog - -[log] -value = 4 -sinks = logfile, syslog - -; Each sink needs to have it's own section. -; -; COMMON FOR EVERY SINK -; -; provider - (required) -; Defines the name of the sink or the special reserved word to -; indicate that it is a sink provided by ELAPI library. -; -; Special sinks provided by ELAPI are: -; file -; syslog -; -; Example: -; provider=file -; -; this would mean the destination for this sink is a file. -; -; If the sink is provided as an external plugin -; the syntax should be the following: -; -; provider=custom_audit -; -; In this case the ELAPI will try to load shared library with the name -; constructed using specified value. In the given example -; ELAPI will try to load libelapi_sink_custom_audit.so library. -; The general pattern is: libelapi_sink_<provider>.so -; -; required - (optional) -; Defines whether it is a required sink? -; If not present the dispatcher will return error at load time. -; -; onerror - if the sink got an error what should dispatcher do? -; 0 - retry (default) -; 1 - disable -; -; timeout - for how long one should wait before trying to revive the sink -; default is 60 seconds -; -; synch - yes/no (default no) - a flag that forces the sink to act synchronously -; even if it can support async operations. -; If application needs to have some events with guaranteed delivery -; and wishes to block for those the implementation should -; send such events to a special target that would consist -; of the sinks that act in the synch mode and guarantee -; the delivery or return failure. - -; SPECIFIC CONFIGURATION PARAMETERS FOR DIFFERENT PROVIDERS -; -; 1) FILE PROVIDER -; -; filename - name of the log file. If not specified <appname>.log will be used. -; Avoid using the same name of the file for different sinks, -; the result might be unpredictable. -; If file name is "stderr" the output will be sent to file descriptor 2. -; If application closed file descriptor 2 the log attempt will -; cause error and onerror value for the sink will be ignored. -; The sink will be permanently disabled causing ELAPI to skip -; it. -; The "keepopen" and "fsyncmode" parameters are ignored for -; "stderr" sink. -; -; keepopen - yes/no (default no) - keep file open -; -; outmode - 0 - CSV like (default) -; 1 - use format specifier -; 2 - HTML -; 3 - XML -; 4 - JSON -; 5 - key-value pairs -; -; set - use only specific subset of fields in the given order -; comma separated list of field names that are expected from -; an event -; The set can optionally end with an item: -; @ - this would indicate that all the rest of the fields need to -; be added at the end as separate fields. -; @n - where n is one of the modes from "outmode" list. -; in this case the all remaining fields will be jammed into one field -; using specified format. In case of CSV jammed into CSV it is recommended -; to use qualifier and set cvsescape to true -; If the @ sign is absent only fields from the specified set will be -; included into the output. -; If event does not contain a specific field it will be empty in the output. -; -; fsyncmode - Defines if the data needs to be flushed to disk and how frequently -; If this value is missing or 0 - no flushing. -; If it is positive it denotes the number of events before next flush. -; If it is negative it denotes the number of seconds before next flush. -; Ignored if file is opened and closed each time. -; -; marker - (optional) -; Default is "\n". -; Marker specifies a line that will be inserted into the file to denote -; the beginning of a new run. The provided string is used as is -; as a format argument for the strftime() function. The string can -; contain zero or one time stamp format specifier listed in a man page -; for the strftime function(). Providing an invalid marker can -; potentially cause your application to crash. -; -; -; Format specific parameters: -; -; CSV related parameters (all optional): -; -; csvqual - what to use as string qualifier for CSV outmode. -; One character string. -; If empty no qualifier is used. -; If not specified then double quote is used. -; csvsep - what to use as CSV field separator. -; One character string. -; If empty no separator is used. -; If not specified comma is used. -; csvescsym - which symbol to use as escape symbol. -; One character string. -; If empty or no qualifier no escaping is done. -; If missing the "\" (backslash) is used. -; Escaping is done only if both the qualifier -; and the escape symbol are not empty. -; csvspace - what to use as space after the separator. Default is space. -; use "space" for space -; use "tab" for tab -; use "cr" for new line -; Other value would cause an error. -; csvnumsp - number of space characters to use. Default is 1. -; csvheader - yes/no (default no). Include header into csv file. -; Respected only if the "set" is explicitely defined. -; -; -; HTML related parameters -; -; htmlheader - create header row -; ... TO BE Continued... - -[debugfile] -provider=file -required=true -onerror=1 -timeout=90 - -[logfile] -provider=file -required=true -onerror=0 -timeout=60 - -[auditfile] -provider=file -required=true -onerror=1 -timeout=90 - -[screen] -provider=file -filename=stderr -keepopen=false -synch=false -onerror=0 -fsyncmode=-10 -set=a, b, c, @0 - -[syslog] -provider=syslog -synch=yes diff --git a/common/elapi/elapi_test/m4/.dir b/common/elapi/elapi_test/m4/.dir deleted file mode 100644 index e69de29b..00000000 --- a/common/elapi/elapi_test/m4/.dir +++ /dev/null diff --git a/common/elapi/elapi_tm.h b/common/elapi/elapi_tm.h deleted file mode 100644 index e9d50e4b..00000000 --- a/common/elapi/elapi_tm.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - ELAPI - - Private header to define internal structure of the ELAPI timer data. - - 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/>. -*/ - -#ifndef ELAPI_TM_H -#define ELAPI_TM_H - -#include "elapi_priv.h" - -/* Structure that holds ELAPI timer watch data */ -struct elapi_tm_data { - void *ext_data; - struct elapi_dispatcher *handle; - struct elapi_sink_ctx *sink_ctx; - struct collection_item *event; -}; - -/* Create the tm data structure for the event */ -int elapi_create_tm_data(struct elapi_tm_data **tm_data, - void *ext_data, - struct elapi_sink_ctx *sink_ctx, - struct collection_item *event); - - -#endif diff --git a/common/elapi/m4/.dir b/common/elapi/m4/.dir deleted file mode 100644 index e69de29b..00000000 --- a/common/elapi/m4/.dir +++ /dev/null diff --git a/common/elapi/providers/file/file_fmt_csv.c b/common/elapi/providers/file/file_fmt_csv.c deleted file mode 100644 index 1a198711..00000000 --- a/common/elapi/providers/file/file_fmt_csv.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - ELAPI - - Module contains functions related to outputting events in CSV format. - - 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 <stdlib.h> /* for free() */ -#include <string.h> /* for strcmp() */ - -#include "collection.h" -#include "file_fmt_csv.h" -#include "collection_tools.h" -#include "ini_config.h" -#include "trace.h" -#include "config.h" - -/* Reasonable size for one event */ -/* FIXME: may be it would make sense to make it configurable ? */ -#define FILE_CSV_BLOCK 256 - -/* Calculate the potential size of the item */ -static unsigned file_csv_data_len(struct file_csv_cfg *cfg, - int type, - int raw_len) -{ - int serialized_len = 0; - - TRACE_FLOW_STRING("file_csv_data_len", "Entry point"); - - switch (type) { - case COL_TYPE_INTEGER: - case COL_TYPE_UNSIGNED: - case COL_TYPE_LONG: - case COL_TYPE_ULONG: - serialized_len = MAX_LONG_STRING_LEN; - break; - - case COL_TYPE_STRING: - if ((cfg->csvqualifier) && - (cfg->csvescchar)) serialized_len = raw_len * 2; - else serialized_len = raw_len; - break; - - case COL_TYPE_BINARY: - serialized_len = raw_len * 2; - break; - - case COL_TYPE_DOUBLE: - serialized_len = MAX_DOUBLE_STRING_LEN; - break; - - case COL_TYPE_BOOL: - serialized_len = MAX_BOOL_STRING_LEN; - break; - - default: - serialized_len = 0; - break; - } - - if (cfg->csvqualifier) serialized_len += 2; - - TRACE_FLOW_STRING("file_csv_data_len", "Exit point"); - return (uint32_t)serialized_len; -} - -/* Copy data escaping characters */ -int file_copy_esc(char *dest, - const char *source, - unsigned char what_to_esc, - unsigned char what_to_use) -{ - int i = 0; - int j = 0; - - while (source[i]) { - if ((source[i] == what_to_use) || - (source[i] == what_to_esc)) { - - dest[j] = what_to_use; - j++; - - } - dest[j] = source[i]; - i++; - j++; - } - - return j; -} - -/* Serialize item into the csv format */ -int file_serialize_csv(struct elapi_data_out *out_data, - int type, - int length, - void *data, - void *mode_cfg) -{ - int error = EOK; - struct file_csv_cfg *cfg; - uint32_t projected_len; - uint32_t used_len; - int first = 1; - int i; - - TRACE_FLOW_STRING("file_serialize_csv", "Entry"); - - cfg = (struct file_csv_cfg *)mode_cfg; - - /* Get projected length of the item */ - projected_len = file_csv_data_len(cfg, type, length); - - TRACE_INFO_NUMBER("Expected data length: ", projected_len); - - /* Make sure we have enough space */ - if (out_data->buffer != NULL) { - TRACE_INFO_STRING("Not a first time use.", "Adding length overhead"); - if (cfg->csvseparator) projected_len++; - projected_len += cfg->csvnumsp; - first = 0; - } - else { - /* Add null terminating zero */ - projected_len++; - } - - /* Grow buffer if needed */ - error = elapi_grow_data(out_data, - projected_len, - FILE_CSV_BLOCK); - if (error) { - TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", error); - return error; - } - - /* Now everything should fit */ - if (!first) { - /* Add separator if any */ - if (cfg->csvseparator) { - out_data->buffer[out_data->length] = cfg->csvseparator; - out_data->length++; - } - - /* Add spaces if any */ - memset(&out_data->buffer[out_data->length], - cfg->csvspace, - cfg->csvnumsp); - } - - /* Add qualifier */ - if (cfg->csvqualifier) { - out_data->buffer[out_data->length] = cfg->csvqualifier; - out_data->length++; - } - - /* Add the value */ - switch (type) { - case COL_TYPE_STRING: - - if ((cfg->csvqualifier) && (cfg->csvescchar)) { - /* Qualify and escape */ - used_len = file_copy_esc((char *)&out_data->buffer[out_data->length], - (const char *)(data), - cfg->csvqualifier, - cfg->csvescchar); - } - else { - /* No escaping so just copy without trailing 0 */ - /* Item's length includes trailing 0 for data items */ - used_len = length - 1; - memcpy(&out_data->buffer[out_data->length], - (const char *)(data), - used_len); - } - break; - - case COL_TYPE_BINARY: - - for (i = 0; i < length; i++) - sprintf((char *)&out_data->buffer[out_data->length + i * 2], - "%02X", (unsigned int)(((const unsigned char *)(data))[i])); - used_len = length * 2; - break; - - case COL_TYPE_INTEGER: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%d", *((const int *)(data))); - break; - - case COL_TYPE_UNSIGNED: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%u", *((const unsigned int *)(data))); - break; - - case COL_TYPE_LONG: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%ld", *((const long *)(data))); - break; - - case COL_TYPE_ULONG: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%lu", *((const unsigned long *)(data))); - break; - - case COL_TYPE_DOUBLE: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%.4f", *((const double *)(data))); - break; - - case COL_TYPE_BOOL: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%s", - (*((const unsigned char *)(data))) ? "true" : "false"); - break; - - default: - out_data->buffer[out_data->length] = '\0'; - used_len = 0; - break; - } - - /* Adjust length */ - out_data->length += used_len; - - /* Add qualifier */ - if (cfg->csvqualifier) { - out_data->buffer[out_data->length] = cfg->csvqualifier; - out_data->length++; - } - - /* The "length" member of the structure does not account - * for the 0 symbol but we made sure that it fits - * when we asked for the memory at the top. - */ - out_data->buffer[out_data->length] = '\0'; - - TRACE_INFO_STRING("Data: ", (char *)out_data->buffer); - - TRACE_FLOW_STRING("file_serialize_csv.", "Exit"); - return error; - -} - -/* Function that reads the specific configuration - * information about the format of the output - */ -int file_get_csv_cfg(void **storage, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - struct collection_item *cfg_item = NULL; - struct file_csv_cfg *cfg= NULL; - const char *qual; - const char *sep; - const char *esc; - const char *space; - - TRACE_FLOW_STRING("file_get_csv_cfg", "Entry"); - - /* Allocate memory for configuration */ - cfg = (struct file_csv_cfg *) calloc(1, sizeof(struct file_csv_cfg)); - if (cfg == NULL) { - TRACE_ERROR_NUMBER("Failed to allocate storage for CSV configuration", ENOMEM); - return ENOMEM; - } - - /*********** Qualifier *************/ - - /* Get qualifier */ - error = get_config_item(name, - FILE_CSV_QUAL, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read qualifier attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have qualifier? */ - if (cfg_item == NULL) { - /* There is no qualifier - use default */ - cfg->csvqualifier = FILE_CSV_DEF_QUAL; - } - else { - /* Get qualifier from configuration */ - error = EOK; - qual = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - if (qual[0] == '\0') cfg->csvqualifier = '\0'; - else if(qual[1] != '\0') { - TRACE_ERROR_STRING("Qualifier has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - else cfg->csvqualifier = qual[0]; - } - - /*********** Separator *************/ - - /* Get separator */ - error = get_config_item(name, - FILE_CSV_SEP, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read separator attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have separator? */ - if (cfg_item == NULL) { - /* There is no separator - use default */ - cfg->csvseparator = FILE_CSV_DEF_SEP; - } - else { - /* Get separator from configuration */ - error = EOK; - sep = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - if (sep[0] == '\0') cfg->csvseparator = '\0'; - else if(sep[1] != '\0') { - TRACE_ERROR_STRING("Separator has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - else cfg->csvseparator = sep[0]; - } - - /*********** Escape symbol *************/ - - /* Get escape symbol */ - error = get_config_item(name, - FILE_CSV_ESCSYM, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read esc symbol attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have esc symbol? */ - if (cfg_item == NULL) { - /* There is no esc symbol - use default */ - cfg->csvescchar = FILE_CSV_DEF_ESC; - } - else { - /* Get esc symbol from configuration */ - error = EOK; - esc = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - if (esc[0] == '\0') cfg->csvescchar = '\0'; - else if(esc[1] != '\0') { - TRACE_ERROR_STRING("Esc symbol has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - else cfg->csvescchar = esc[0]; - } - - /*********** Space *************/ - - /* Get space */ - error = get_config_item(name, - FILE_CSV_SPACE, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read space attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have space? */ - if (cfg_item == NULL) { - /* There is no esc symbol - use default */ - cfg->csvspace = FILE_CSV_DEF_SPC; - } - else { - /* Get file name from configuration */ - error = EOK; - space = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - /* Determine what to use as a space symbol */ - if (space[0] == '\0') cfg->csvspace = ' '; - else if(strcmp(space, FILE_CSV_SP) == 0) cfg->csvspace = ' '; - else if(strcmp(space, FILE_CSV_TAB) == 0) cfg->csvspace = '\t'; - else if(strcmp(space, FILE_CSV_CR) == 0) cfg->csvspace = '\n'; - else { - TRACE_ERROR_STRING("Esc symbol has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - } - - /*********** Number of spaces *************/ - /* Get number of spaces */ - - cfg_item = NULL; - error = get_config_item(name, - FILE_CSV_NUMSP, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read number of spaces attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have number of spaces? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No attribute.", "Assume no spaces"); - cfg->csvnumsp = 0; - } - else { - cfg->csvnumsp = (uint32_t) get_unsigned_config_value(cfg_item, 1, 0, &error); - if (error) { - TRACE_ERROR_STRING("Invalid number of spaces value", "Fatal Error!"); - free(cfg); - return EINVAL; - } - /* Check for right range */ - if (cfg->csvnumsp > FILE_MAXSPACE) { - TRACE_ERROR_STRING("Too many spaces - not allowed", "Fatal Error!"); - free(cfg); - return ERANGE; - } - } - - /*********** Header *************/ - /* Next is header field */ - - cfg_item = NULL; - error = get_config_item(name, - FILE_CSV_HEADER, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read header attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have header? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No attribute.", "Assume no header"); - cfg->csvheader = 0; - } - else { - cfg->csvheader = (uint32_t) get_bool_config_value(cfg_item, '\0', &error); - if (error) { - TRACE_ERROR_STRING("Invalid csv header value", "Fatal Error!"); - free(cfg); - return EINVAL; - } - } - - *((struct file_csv_cfg **)storage) = cfg; - - TRACE_FLOW_STRING("file_get_csv_cfg", "Entry"); - return error; -} - -#ifdef ELAPI_VERBOSE - -void file_print_fmt_csv(void *data) -{ - struct file_csv_cfg *cfg; - - cfg = (struct file_csv_cfg *)(data); - if (cfg == NULL) { - printf("CSV Configuration is undefined!\n"); - return; - } - - printf("CSV Configuration:\n"); - printf(" Qualifier: "); - if (cfg->csvqualifier != '\0') printf("[%c]\n", cfg->csvqualifier); - else printf("[undefined]\n"); - - printf(" Separator: "); - if (cfg->csvseparator != '\0') printf("[%c]\n", cfg->csvseparator); - else printf("[undefined]\n"); - - printf(" Escape: "); - if (cfg->csvescchar != '\0') printf("[%c]\n", cfg->csvescchar); - else printf("[undefined]\n"); - - printf(" Space: [%c] [ASCII: %d]\n", cfg->csvspace, (int)(cfg->csvspace)); - printf(" Number of spaces: [%d]\n", cfg->csvnumsp); - printf(" Header: [%s]\n", ((cfg->csvheader > 0) ? "yes" : "no")); - printf("CSV Configuration END\n"); - -} -#endif diff --git a/common/elapi/providers/file/file_fmt_csv.h b/common/elapi/providers/file/file_fmt_csv.h deleted file mode 100644 index 6cc52745..00000000 --- a/common/elapi/providers/file/file_fmt_csv.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - ELAPI - - Module contains functions related to outputting events in CSV format. - - 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/>. -*/ - -#ifndef ELAPI_FILE_FMT_CSV_H -#define ELAPI_FILE_FMT_CSV_H - -#include <stdint.h> -#include "collection.h" -#include "elapi_basic.h" - -/* Format specific configuration parameters */ -/* CSV: */ -#define FILE_CSV_QUAL "csvqual" -#define FILE_CSV_SEP "csvsep" -#define FILE_CSV_ESCSYM "csvescsym" -#define FILE_CSV_SPACE "csvspace" -#define FILE_CSV_NUMSP "csvnumsp" -#define FILE_CSV_HEADER "csvheader" - -/* Strings from config that will be recognized */ -#define FILE_CSV_SP "space" -#define FILE_CSV_TAB "tab" -#define FILE_CSV_CR "cr" - - -/* Default values for configuration parameters */ -#define FILE_CSV_DEF_QUAL '"' -#define FILE_CSV_DEF_SEP ',' -#define FILE_CSV_DEF_ESC '\\' -#define FILE_CSV_DEF_SPC ' ' - -/* Try catch corrupted configuration 80 is more than enough */ -#define FILE_MAXSPACE 80 - -/* Configuration for the CSV output */ -struct file_csv_cfg { - uint32_t csvheader; /* Include csv header or not? */ - uint32_t csvnumsp; /* How many spaces ? */ - unsigned char csvqualifier; /* What is the qualifier? */ - unsigned char csvseparator; /* What is the separator? */ - unsigned char csvescchar; /* What is the escape character? */ - unsigned char csvspace; /* What is the space character? */ -}; - -/* Function that reads the specific configuration - * information about the CSV format of the output - */ -int file_get_csv_cfg(void **storage, - const char *name, - struct collection_item *ini_config, - const char *appname); - -/* Serialize an item into the csv format */ -int file_serialize_csv(struct elapi_data_out *out_data, - int type, - int length, - void *data, - void *mode_cfg); - - -#ifdef ELAPI_VERBOSE -/* Function for debugging */ -void file_print_fmt_csv(void *data); - -#endif -#endif diff --git a/common/elapi/providers/file/file_provider.c b/common/elapi/providers/file/file_provider.c deleted file mode 100644 index 652e6468..00000000 --- a/common/elapi/providers/file/file_provider.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - ELAPI - - Module implements a provider for sinks based on file. - - 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 <stdlib.h> /* for free() */ -#include <string.h> /* for strlen() */ -#include <unistd.h> /* for close() */ - -#include "file_provider.h" -#include "file_util.h" -#include "file_fmt_csv.h" -#include "ini_config.h" -#include "trace.h" -#include "config.h" - -/* NOTE: Each format module has its own header */ -#include "file_fmt_csv.h" -/* Add headers for new formats here... */ - -/*******************************************************************/ -/* SECTION FOR INTERNAL CONDITIONALLY COMPILED DEBUGGING FUNCTIONS */ -/*******************************************************************/ -#ifdef ELAPI_VERBOSE -#include "collection_tools.h" - -/* Function to debug format configurations */ -void file_print_fmt_cfg(uint32_t mode, void *fmt_cfg) -{ - switch(mode) { - case FILE_MODE_CSV: - file_print_fmt_csv(fmt_cfg); - break; - /* FIXME : add other formats later */ -/* - case FILE_MODE_FORMAT: - error = file_print_fmt_format(fmt_cfg); - break; - case FILE_MODE_HTML: - error = file_print_fmt_html(fmt_cfg); - break; - case FILE_MODE_XML: - error = file_print_fmt_xml(fmt_cfg); - break; - case FILE_MODE_JSON: - error = file_print_fmt_json(fmt_cfg); - break; - case FILE_MODE_KVP: - error = file_print_fmt_kvp(fmt_cfg); - break; -*/ - default: - printf("Unsupported mode!\n"); - } -} - - -/* Function for debugging configuration */ -void file_print_cfg(struct file_prvdr_cfg *cfg) -{ - printf("File provider configuration\n"); - - printf(" File name: [%s]\n", ((cfg->filename != NULL) ? cfg->filename : "NULL")); - printf(" Own file : [%s]\n", ((cfg->ownfile > 0) ? "yes" : "no")); - printf(" Keep open: [%s]\n", ((cfg->keepopen > 0) ? "yes" : "no")); - - if (cfg->fsyncmode == 0) { - printf(" Sync mode: [no flush]\n"); - } - else if (cfg->fsyncmode > 0) { - printf(" Sync mode: every [%d] event\n", cfg->fsyncmode); - } - else { - printf(" Sync mode: every [%d] second\n", 0 - cfg->fsyncmode); - } - - if (cfg->set) { - printf(" There is a set of predefined fields\n"); - col_print_collection(cfg->set); - printf(" Use leftovers: [%s]\n", ((cfg->use_leftovers > 0) ? "yes" : "no")); - printf(" Jam leftovers: [%s]\n", ((cfg->jam_leftovers > 0) ? "yes" : "no")); - if (cfg->use_leftovers > 0) { - printf("Leftovers configuration:\n"); - file_print_fmt_cfg(cfg->mode_leftovers, cfg->lo_fmt_cfg); - printf("Leftovers configuration END\n"); - } - } - else printf("All fields go into the output.\n"); - - - printf("Main configuration:\n"); - file_print_fmt_cfg(cfg->outmode, cfg->main_fmt_cfg); - printf("Main configuration END:\n"); - - printf("File provider configuration END\n"); - -} - -/* Function to debug context */ -void file_print_ctx(struct file_prvdr_ctx *ctx) -{ - if (ctx == NULL) { - printf("No file provider context!\n"); - return; - } - - printf("File Provider Context\n"); - - /* Print configuration */ - file_print_cfg(&(ctx->config)); - - /* Print other parts of the context */ - printf("File is currently: [%s]\n", ((ctx->outfile >= 0) ? "open" : "closed")); - printf("File Provider Context END\n\n"); - -} -#endif - -/*******************************************************************/ -/* MAIN MODULE FUNCTIONS */ -/*******************************************************************/ - -/* Function that reads the specific configuration - * information about the format of the output - */ -static int file_read_fmt_cfg(void **storage, - uint32_t mode, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - - TRACE_FLOW_STRING("file_read_fmt_cfg", "Entry"); - - switch(mode) { - case FILE_MODE_CSV: - error = file_get_csv_cfg(storage, name, ini_config, appname); - break; - /* FIXME : add other formats later */ -/* - case FILE_MODE_FORMAT: - error = file_get_format_cfg(storage, name, ini_config, appname); - break; - case FILE_MODE_HTML: - error = file_get_html_cfg(storage, name, ini_config, appname); - break; - case FILE_MODE_XML: - error = file_get_xml_cfg(storage, name, ini_config, appname); - break; - case FILE_MODE_JSON: - error = file_get_json_cfg(storage, name, ini_config, appname); - break; - case FILE_MODE_KVP: - error = file_get_kvp_cfg(storage, name, ini_config, appname); - break; -*/ - default: - TRACE_ERROR_STRING("Unsupported mode", "Fatal error!"); - error = EINVAL; - - } - TRACE_FLOW_NUMBER("file_read_fmt_cfg. Exit. Returning:", error); - return error; -} - -/* Function to build the set object from the configuration data */ -static int file_build_set(struct file_prvdr_cfg *file_cfg, - struct collection_item *cfg_item) -{ - int error = EOK; - char **fields; - char *field; - int size; - int count; - struct collection_item *dummy = NULL; - struct collection_item *set = NULL; - - TRACE_FLOW_STRING("file_build_set", "Entry"); - - /* Get fields array from config field */ - fields = get_string_config_array(cfg_item, NULL, &size, &error); - if (error) { - TRACE_ERROR_NUMBER("Attempt to get set items returned error", error); - return error; - } - - if (size > 0) { - - TRACE_INFO_STRING("We have the set of required fields", ""); - - /* Create collection */ - error = col_create_collection(&set, FILE_FIELDSET_COL, FILE_FIELDSET_CLASS); - if (error) { - TRACE_ERROR_NUMBER("Attempt to create collection failed", error); - return error; - } - - for (count = 0; count < size; count++) { - field = fields[count]; - TRACE_INFO_STRING("FIELD:", field); - - if (field[0] == FILE_SET_END) { - TRACE_INFO_STRING("Leftovers field found.", ""); - if (count != (size - 1)) { - /* We found an end list field in the middle - error */ - TRACE_ERROR_NUMBER("More fields after end list field.", EINVAL); - col_destroy_collection(set); - free_string_config_array(fields); - return EINVAL; - } - - file_cfg->use_leftovers = 1; - - /* What format to use leftovers ? */ - /* NOTE: Is we ever support more than 10 formats - * this logic needs to change - */ - if ((field[1] >= '0') && - (field[1] <= ('0' + FILE_MAXMODE)) && - (field[2] == '\0')) { - /* We have a format specifier */ - file_cfg->mode_leftovers = (uint32_t)(field[1] - '0'); - file_cfg->jam_leftovers = 1; - TRACE_INFO_NUMBER("Use mode for leftovers:", file_cfg->mode_leftovers); - } - else { - /* Wrong format */ - TRACE_ERROR_NUMBER("Leftover field has invalid format.", EINVAL); - col_destroy_collection(set); - free_string_config_array(fields); - return EINVAL; - } - - } - else { - error = col_add_binary_property(set, - NULL, - field, - &dummy, - sizeof(struct collection_item *)); - if (error) { - TRACE_ERROR_NUMBER("Error adding item to the set.", error); - col_destroy_collection(set); - free_string_config_array(fields); - return error; - } - } - } - - file_cfg->set = set; - } - - /* Free the list */ - free_string_config_array(fields); - - TRACE_FLOW_STRING("file_build_set", "Exit"); - return error; -} - - -/* Function to read configuration */ -static int file_read_cfg(struct file_prvdr_cfg *file_cfg, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - struct collection_item *cfg_item = NULL; - const char *filename; - int use_default_name = 0; - - TRACE_FLOW_STRING("file_read_cfg", "Entry point"); - - /*********** Filename *************/ - - /* Get file name */ - error = get_config_item(name, - FILE_OUTNAME, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"filename\" attribute returned error", error); - return error; - } - - /* Do we have file name? */ - if (cfg_item == NULL) use_default_name = 1; - else { - /* Get file name from configuration */ - error = EOK; - filename = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - return error; - } - /* Check if file name is empty */ - if (filename[0] == '\0') use_default_name = 1; - else { - /* Now get a copy */ - file_cfg->filename = get_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to copy value from configuration.", "Fatal Error!"); - return error; - } - } - } - - if (use_default_name) { - /* There is no file name - use default */ - file_cfg->filename = malloc(strlen(appname) + sizeof(FILE_SUFFIX)); - if (file_cfg->filename == NULL) { - TRACE_ERROR_STRING("Failed to allocate memory for file name.", "Fatal Error!"); - return ENOMEM; - } - /* Appname is validated in the elapi_log.c */ - /* This should be safe to do */ - strcpy(file_cfg->filename, appname); - strcat(file_cfg->filename, FILE_SUFFIX); - - file_cfg->ownfile = 1; - } - else if (strcmp(filename, FILE_STDERR) != 0) file_cfg->ownfile = 1; - else file_cfg->ownfile = 0; - - /*********** Keep open *************/ - /* Next is "keepopen" field */ - - cfg_item = NULL; - error = get_config_item(name, - FILE_KEEPOPEN, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"keepopen\" attribute returned error", error); - return error; - } - - /* Do we have "keepopen"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"keepopen\" attribute.", "Assume open on each entry"); - file_cfg->keepopen = 0; - } - else { - file_cfg->keepopen = (uint32_t) get_bool_config_value(cfg_item, '\0', &error); - if (error) { - TRACE_ERROR_STRING("Invalid \"keepopen\" value", "Fatal Error!"); - return EINVAL; - } - } - - /*********** Outmode *************/ - /* Next is "outmode" field */ - - cfg_item = NULL; - error = get_config_item(name, - FILE_OUTMODE, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"outmode\" attribute returned error", error); - return error; - } - - /* Do we have "outmode"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"outmode\" attribute.", "Assume CSV kind"); - file_cfg->outmode = 0; - } - else { - file_cfg->outmode = (uint32_t) get_unsigned_config_value(cfg_item, 1, 0, &error); - if (error) { - TRACE_ERROR_STRING("Invalid \"outmode\" value", "Fatal Error!"); - return EINVAL; - } - /* Check for right range */ - if (file_cfg->outmode > FILE_MAXMODE) { - TRACE_ERROR_STRING("Invalid \"outmode\" value - out of range", "Fatal Error!"); - return ERANGE; - } - } - - /*********** Sync mode *************/ - /* Next is sync mode field */ - - cfg_item = NULL; - error = get_config_item(name, - FILE_FLUSH, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"fsyncmode\" attribute returned error", error); - return error; - } - - /* Do we have "fsyncmode"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"fsyncmode\" attribute.", "Assume CSV kind"); - file_cfg->fsyncmode = 0; - } - else { - file_cfg->fsyncmode = (int32_t) get_int_config_value(cfg_item, 1, 0, &error); - if (error) { - TRACE_ERROR_STRING("Invalid \"fsyncmode\" value", "Fatal Error!"); - return EINVAL; - } - } - - /*********** Set *************/ - /* Next is the "set" field */ - cfg_item = NULL; - error = get_config_item(name, - FILE_FIELDSET, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read \"set\" attribute returned error", error); - return error; - } - - file_cfg->use_leftovers = 0; - file_cfg->jam_leftovers = 0; - file_cfg->mode_leftovers = file_cfg->outmode; - - /* Do we have "required"? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No \"set\" attribute.", "Assume all fields as specified"); - file_cfg->set = NULL; - } - else { - error = file_build_set(file_cfg, cfg_item); - if (error) { - TRACE_ERROR_STRING("Invalid \"set\" value", "Fatal Error!"); - return EINVAL; - } - } - - /*********** Format specific configurations *************/ - /* Read the main format configuration details */ - error = file_read_fmt_cfg((void **)(&(file_cfg->main_fmt_cfg)), - file_cfg->outmode, - name, - ini_config, - appname); - if (error) { - TRACE_ERROR_NUMBER("Failed to read main format configuration", error); - return error; - } - - if (file_cfg->use_leftovers) { - /* If we use same mode for leftovers and main do not read things again */ - if (file_cfg->mode_leftovers == file_cfg->outmode) { - TRACE_INFO_STRING("Output modes are the same", ""); - file_cfg->lo_fmt_cfg = file_cfg->main_fmt_cfg; - } - else { - TRACE_INFO_STRING("Output modes are the different", ""); - TRACE_INFO_NUMBER("Main mode", file_cfg->outmode); - TRACE_INFO_NUMBER("Left over's mode", file_cfg->mode_leftovers); - - /* Read the leftover's format configuration details */ - error = file_read_fmt_cfg((void **)(&(file_cfg->lo_fmt_cfg)), - file_cfg->mode_leftovers, - name, - ini_config, - appname); - if (error) { - TRACE_ERROR_NUMBER("Failed to read main format configuration", error); - return error; - } - } - } - TRACE_FLOW_STRING("file_read_cfg", "Exit"); - return error; -} - -/* Function to destroy the context */ -static void file_destroy_ctx(struct file_prvdr_ctx **file_ctx) -{ - TRACE_FLOW_STRING("file_destroy_ctx", "Entry"); - - if ((file_ctx) && (*file_ctx)) { - /* Close file if it is open */ - if (((*file_ctx)->outfile >= 0) && ((*file_ctx)->config.ownfile)) { - TRACE_INFO_STRING("File was open", ""); - close((*file_ctx)->outfile); - } - - /* Free file name if it is not NULL */ - if ((*file_ctx)->config.filename) { - TRACE_INFO_STRING("Freeing file name", (*file_ctx)->config.filename); - free((*file_ctx)->config.filename); - } - - /* Free set if any */ - if ((*file_ctx)->config.set) { - TRACE_INFO_NUMBER("Freeing set", (*file_ctx)->config.set); - col_destroy_collection((*file_ctx)->config.set); - } - - /* Free main format configuration if it is not NULL */ - if (((*file_ctx)->config.main_fmt_cfg) && - ((*file_ctx)->config.main_fmt_cfg != (*file_ctx)->config.lo_fmt_cfg)) { - TRACE_INFO_NUMBER("Freeing main format config.", (*file_ctx)->config.main_fmt_cfg); - free((*file_ctx)->config.main_fmt_cfg); - } - - /* Free left over format configuration if it is not NULL */ - if ((*file_ctx)->config.lo_fmt_cfg) { - TRACE_INFO_NUMBER("Freeing leftover format config.", (*file_ctx)->config.lo_fmt_cfg); - free((*file_ctx)->config.lo_fmt_cfg); - } - - TRACE_FLOW_STRING("Freeing file context", "Entry"); - free(*file_ctx); - *file_ctx = NULL; - } - - TRACE_FLOW_STRING("file_destroy_ctx", "Exit"); -} - -/* Function to create context */ -static int file_create_ctx(struct file_prvdr_ctx **file_ctx, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - struct file_prvdr_ctx *ctx = NULL; - - TRACE_FLOW_STRING("file_create_ctx", "Entry point"); - - ctx = (struct file_prvdr_ctx *)calloc(1, sizeof(struct file_prvdr_ctx)); - if (ctx == NULL) { - TRACE_ERROR_NUMBER("Failed to allocate context", ENOMEM); - return ENOMEM; - } - /* Init items */ - ctx->outfile = -1; - - /* Read configuration data */ - error = file_read_cfg(&(ctx->config), name, ini_config, appname); - if (error) { - TRACE_ERROR_NUMBER("Error reading sink configuration", error); - file_destroy_ctx(&ctx); - return error; - } - - *file_ctx = ctx; - - TRACE_FLOW_STRING("file_create_ctx", "Exit"); - return error; -} - - -/* File init function */ -int file_init(void **priv_ctx, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - TRACE_FLOW_STRING("file_init", "Entry point"); - - /* Start with creating context */ - error = file_create_ctx((struct file_prvdr_ctx **)priv_ctx, - name, - ini_config, - appname); - if (error) { - TRACE_ERROR_NUMBER("Failed to create context", error); - return error; - } - - /* Open file */ - /* FIXME: ... */ - -#ifdef ELAPI_VERBOSE - printf("Initializaing file provider for sink: [%s]\n", name); - file_print_ctx(*((struct file_prvdr_ctx **)priv_ctx)); -#endif - - TRACE_FLOW_STRING("file_init", "Exit"); - return error; -} - -/* File close function */ -void file_close(void **priv_ctx) -{ - struct file_prvdr_ctx **ctx = NULL; - - TRACE_FLOW_STRING("file_close", "Entry point"); - - ctx = (struct file_prvdr_ctx **)priv_ctx; - -#ifdef ELAPI_VERBOSE - file_print_ctx(*ctx); -#endif - - file_destroy_ctx(ctx); - - TRACE_FLOW_STRING("file_close", "Exit"); -} - -/* File submit function */ -int file_submit(void *priv_ctx, struct collection_item *event) -{ - int error = EOK; - struct file_prvdr_ctx *ctx = (struct file_prvdr_ctx *)priv_ctx; - struct elapi_data_out *out_data; - - TRACE_FLOW_STRING("file_submit", "Entry point"); - -#ifdef ELAPI_VERBOSE - file_print_ctx(ctx); - - /* FIXME: Placeholder for now */ - col_print_collection(event); -#endif - - /* FIXME: Open file here if it is closed */ - - error = file_prep_data(&out_data, ctx, event); - if (error) { - TRACE_ERROR_NUMBER("Failed to prepare data", error); - return error; - } - - /* FIXME: just print it for now!!! */ - - printf("EVENT: [%*s]\n", out_data->length, out_data->buffer); - - - /* FIXME: write data base on the synch or not synch mode of the sink */ - /* For now we will just assume synch */ - /* This function will probably be a part of the common callbacks */ - /* elapi_write_to_fd(out_data, ctx_>outfile); */ - - /* This one is temporary here too */ - elapi_free_serialized_data(out_data); - - TRACE_FLOW_STRING("file_sumbit", "Exit"); - return error; -} - - -/* This is the equivalent of the get info function */ -void file_ability(struct sink_cpb *cpb_block) -{ - TRACE_FLOW_STRING("file_ability", "Entry point"); - - cpb_block->init_cb = file_init; - cpb_block->submit_cb = file_submit; - cpb_block->close_cb = file_close; - - TRACE_FLOW_STRING("file_ability", "Exit"); -} diff --git a/common/elapi/providers/file/file_provider.h b/common/elapi/providers/file/file_provider.h deleted file mode 100644 index f5e6753d..00000000 --- a/common/elapi/providers/file/file_provider.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - ELAPI - - Header file used internally by the "file" provider. - - 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/>. -*/ - -#ifndef ELAPI_FILE_PROVIDER_H -#define ELAPI_FILE_PROVIDER_H - -#include <stdint.h> - -#include "elapi_sink.h" - -/* Common configuration parameters */ -#define FILE_OUTNAME "filename" -#define FILE_KEEPOPEN "keepopen" -#define FILE_OUTMODE "outmode" -#define FILE_FIELDSET "set" -#define FILE_FORMAT "format" -#define FILE_FLUSH "fsyncmode" - - -/* Max supported mode */ -/* NOTE: Increase this value when you add a new mode. - * If it ever gets to 10 the logic in the - * function that builds the set needs to change. - */ -#define FILE_MAXMODE 5 -/* Modes: */ -#define FILE_MODE_CSV 0 -#define FILE_MODE_FORMAT 1 -#define FILE_MODE_HTML 2 -#define FILE_MODE_XML 3 -#define FILE_MODE_JSON 4 -#define FILE_MODE_KVP 5 - - -/* FIXME: Should it be a compile time switch? */ -#define FILE_SUFFIX ".log" -#define FILE_SET_END '@' - -/* Field set collection */ -#define FILE_FIELDSET_COL "set" -#define FILE_FIELDSET_CLASS 21000 - -/* Special file name - stderr is handled differently */ -#define FILE_STDERR "stderr" - -/* Structure that holds internal configuration of the file - * provider. - */ -struct file_prvdr_cfg { - char *filename; /* File name */ - uint32_t ownfile; /* Do I own the file handle? */ - uint32_t keepopen; /* Do we need to keep file open */ - int32_t fsyncmode; /* How frequently data is fsynced */ - uint32_t outmode; /* Output mode */ - struct collection_item *set; /* Field set without leftovers symbol */ - uint32_t use_leftovers; /* Was there a leftover symbol */ - uint32_t jam_leftovers; /* leftovers should be serialized into one field */ - uint32_t mode_leftovers; /* Format for the leftover fields */ - void *main_fmt_cfg; /* Configuration data for the main format */ - void *lo_fmt_cfg; /* Configuration data for leftovers format */ - /* FIXME add other config data strutures here */ - - /* FIXME: Rotation rules ? */ -}; - - -/* File context */ -struct file_prvdr_ctx { - struct file_prvdr_cfg config; /* Configuration */ - int outfile; /* File handle */ - uint32_t smode; /* Sink's synch mode */ - /* FIXME - other things go here */ -}; - -/* File init function */ -int file_init(void **priv_ctx, - const char *name, - struct collection_item *ini_config, - const char *appname); - -/* File close function */ -void file_close(void **priv_ctx); - -/* File submit function */ -int file_submit(void *priv_ctx, struct collection_item *event); - -/* This is the equivalent of the get info function */ -void file_ability(struct sink_cpb *cpb_block); - -#endif diff --git a/common/elapi/providers/file/file_util.c b/common/elapi/providers/file/file_util.c deleted file mode 100644 index 2e89460b..00000000 --- a/common/elapi/providers/file/file_util.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - ELAPI - - Module contains internal utility functions for the file provider. - - 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 <stdlib.h> /* for free() */ -#include <string.h> /* for strlen() */ - -/* To be able to serialize on needs to know the guts - * of the collection structure so have to include - * private header here. - */ -#include "file_provider.h" -#include "file_util.h" -#include "ini_config.h" -#include "trace.h" -#include "config.h" - -#ifdef ELAPI_VERBOSE -/* FIXME: remove when api is stable */ -#include "collection_tools.h" -#endif - -char empty[] = ""; - -/* Callback to prepare set for splitting */ -static int file_set_clean_cb(const char *property, - int property_len, - int type, - void *data, - int length, - void *custom_data, - int *stop) -{ - int error = EOK; - TRACE_FLOW_STRING("file_set_clean_cb", "Entry"); - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) return EOK; - - /* Clean data */ - *((struct collection_item **)(data)) = NULL; - - TRACE_FLOW_STRING("file_set_clean_cb", "Exit"); - return error; -} - -/* Function to split event into two parts by given set */ -static int file_split_by_set(struct collection_item **leftovers, - struct file_prvdr_cfg *cfg, - struct collection_item *event) -{ - int error = EOK; - struct collection_item *item_event; - struct collection_item *item_set; - struct collection_iterator *it_event; - struct collection_iterator *it_set; - struct collection_item *lo = NULL; - int found = 0; - int len1, len2; - - TRACE_FLOW_STRING("file_split_by_set", "Entry"); - - /* First prepare set for use */ - error = col_traverse_collection(cfg->set, - COL_TRAVERSE_ONELEVEL, - file_set_clean_cb, - NULL); - if (error) { - TRACE_ERROR_NUMBER("Traverse set failed.", error); - return error; - } - - /* If we are going to use leftovers create a collection */ - if (cfg->use_leftovers) { - error = col_create_collection(&lo, - FILE_LO_NAME, - FILE_LO_CLASS); - if (error) { - TRACE_ERROR_NUMBER("Faild to create collection.", error); - return error; - } - } - - /* Now all items from the set are NULLs */ - /* Split the event in two parts */ - /* We need to iterate through the event rather than use a callback. */ - /* Bind iterator */ - error = col_bind_iterator(&it_event, event, COL_TRAVERSE_FLAT); - if (error) { - TRACE_ERROR_NUMBER("Error bind iterator for event failed:", error); - /* Here and below it is safe to destroy it event if is NULL. */ - col_destroy_collection(lo); - return error; - } - - while(1) { - /* Loop through the event */ - error = col_iterate_collection(it_event, &item_event); - if (error) { - TRACE_ERROR_NUMBER("Error iterating event:", error); - col_unbind_iterator(it_event); - col_destroy_collection(lo); - return error; - } - - /* Are we done ? */ - if (item_event == NULL) break; - - /* Skip headers */ - if (col_get_item_type(item_event) == COL_TYPE_COLLECTION) continue; - - /* For each item in the event find an item in the set */ - error = col_bind_iterator(&it_set, cfg->set, COL_TRAVERSE_ONELEVEL); - if (error) { - TRACE_ERROR_NUMBER("Error bind iterator for set failed:", error); - col_unbind_iterator(it_event); - col_destroy_collection(lo); - return error; - } - - found = 0; - while(1) { - /* Loop through the event */ - error = col_iterate_collection(it_set, &item_set); - if (error) { - TRACE_ERROR_NUMBER("Error iterating set:", error); - col_unbind_iterator(it_event); - col_unbind_iterator(it_set); - col_destroy_collection(lo); - return error; - } - - /* Are we done ? */ - if (item_set == NULL) break; - - /* Skip headers */ - if (col_get_item_type(item_set) == COL_TYPE_COLLECTION) continue; - - /* Hashes should match and the data in the set should be NULL, - * and legths should be same. - */ - (void)col_get_item_property(item_event, &len1); - (void)col_get_item_property(item_set, &len2); - - if ((col_get_item_hash(item_event) == col_get_item_hash(item_set)) && - (*((struct collection_item **)(col_get_item_data(item_set))) == NULL) && - (len1 == len2)) { - /* This is a candidate for match - compare strings */ - TRACE_INFO_STRING("Found a good candidate for match.",""); - TRACE_INFO_STRING("Set item:", col_get_item_property(item_set, NULL)); - TRACE_INFO_STRING("Event:", col_get_item_property(item_event, NULL)); - - if (strncasecmp(col_get_item_property(item_set, NULL), - col_get_item_property(item_event, NULL), - len1) == 0) { - TRACE_INFO_STRING("Match found!",""); - TRACE_INFO_STRING("Set item:", col_get_item_property(item_set, NULL)); - TRACE_INFO_STRING("Event:", col_get_item_property(item_event, NULL)); - - *((struct collection_item **)(col_get_item_data(item_set))) = item_event; - found = 1; - break; - } - } - } - /* Done with the set */ - col_unbind_iterator(it_set); - - /* Is it a leftover ? */ - if ((!found) && (cfg->use_leftovers)) { - /* We need to put it in the leftovers pile */ - /* To save time and space we do not care about property name. - * The property name is going to be in the referenced item. - */ - error = col_add_binary_property(lo, - NULL, - "", - (void *)(&item_event), - sizeof(struct collection_item *)); - if (error) { - TRACE_ERROR_NUMBER("Error addding item to leftovers:", error); - col_unbind_iterator(it_event); - col_destroy_collection(lo); - return error; - } - } - } - - /* Done with the event */ - col_unbind_iterator(it_event); - - /* Save leftovers if any */ - *leftovers = lo; - - TRACE_FLOW_STRING("file_spserialized_lo->bufferlit_by_set", "Exit"); - return error; -} - -/* Function to serialize one item */ -static int file_serialize_item(struct elapi_data_out *out_data, - int type, - int length, - void *data, - uint32_t mode, - void *mode_cfg) -{ - int error = EOK; - TRACE_FLOW_STRING("file_serialize_item", "Entry"); - - switch(mode) { - case FILE_MODE_CSV: - error = file_serialize_csv(out_data, - type, - length, - data, - mode_cfg); - break; -/* FIXME : add other iterative formats later */ -/* - case FILE_MODE_HTML: - error = file_serialize_html(out_data, - type, - length, - data, - mode_cfg); - break; - case FILE_MODE_XML: - error = file_serialize_xml(out_data, - type, - length, - data, - mode_cfg); - break; - case FILE_MODE_JSON: - error = file_serialize_json(out_data, - type, - length, - data, - mode_cfg); - break; - case FILE_MODE_KVP: - error = file_serialize_kvp(out_data, - type, - length, - data, - mode_cfg); - break; -*/ - default: - TRACE_ERROR_STRING("Unsupported mode", "Fatal error!"); - error = EINVAL; - - } - - TRACE_FLOW_STRING("file_serialize_item", "Exit"); - return error; - -} - - - -/* Function to serialize the list */ -static int file_serialize_list(struct elapi_data_out **out_data, - int append, - int reference, - struct collection_item *input, - uint32_t mode, - void *mode_cfg) -{ - int error = EOK; - struct elapi_data_out *allocated = NULL; - struct elapi_data_out *to_use = NULL; - struct collection_iterator *iterator; - struct collection_item *item; - - TRACE_FLOW_STRING("file_serialize_list", "Entry"); - - /* Allocate storage if we are not appending */ - if (!append) { - error = elapi_alloc_serialized_data(&allocated); - if (error) { - TRACE_ERROR_NUMBER("Failed to allocated serialized data", error); - return error; - } - TRACE_INFO_STRING("Allocated new out data", ""); - to_use = allocated; - } - else { - TRACE_INFO_STRING("Appening, use passed in output data", ""); - to_use = *out_data; - } - - /* FIXME: This logic works for iterative formats only. */ - /* When we implement the free form format this - * logic should be augmented. */ - -#ifdef ELAPI_VERBOSE - /* FIXME: remove when stable */ - col_debug_collection(input, COL_TRAVERSE_FLAT); -#endif - - - /* Start iterating */ - error = col_bind_iterator(&iterator, input, COL_TRAVERSE_FLAT); - if (error) { - TRACE_ERROR_NUMBER("Error bind iterator failed:", error); - return error; - } - - while(1) { - /* Loop through the collection */ - error = col_iterate_collection(iterator, &item); - if (error) { - TRACE_ERROR_NUMBER("Error iterating event:", error); - col_unbind_iterator(iterator); - /* Free allocated data if we allocated it */ - elapi_free_serialized_data(allocated); - return error; - } - - /* Are we done ? */ - if (item == NULL) break; - - /* Skip headers */ - if (col_get_item_type(item) == COL_TYPE_COLLECTION) continue; - - /* Got item */ - if (reference) { - /* Derefernce the item before using */ - item = *((struct collection_item **)(col_get_item_data(item))); - } - - if (item) { - TRACE_ERROR_NUMBER("Item property", col_get_item_property(item, NULL)); - - /* Serialize this item */ - error = file_serialize_item(to_use, - col_get_item_type(item), - col_get_item_length(item), - col_get_item_data(item), - mode, - mode_cfg); - } - else { - /* Serialize this item */ - error = file_serialize_item(to_use, - COL_TYPE_BINARY, - 0, - NULL, - mode, - mode_cfg); - } - - if (error) { - TRACE_ERROR_NUMBER("Failed to serialize item", error); - col_unbind_iterator(iterator); - /* Free allocated data if we allocated it */ - elapi_free_serialized_data(allocated); - return error; - } - } - col_unbind_iterator(iterator); - - *out_data = to_use; - - TRACE_FLOW_STRING("file_serialize_list", "Exit"); - return error; -} - -/* Function to log event into sink */ -int file_prep_data(struct elapi_data_out **out_data, - struct file_prvdr_ctx *ctx, - struct collection_item *event) -{ - int error = EOK; - struct elapi_data_out *serialized = NULL; - struct elapi_data_out *serialized_lo = NULL; - struct collection_item *leftovers = NULL; - - TRACE_FLOW_STRING("file_prep_data", "Entry"); - - /* Do we need to split the data into two parts by set ? */ - if (ctx->config.set) { - /* Split collection based on the configured set of fields */ - error = file_split_by_set(&leftovers, - &(ctx->config), - event); - if (error) { - TRACE_ERROR_NUMBER("Split collection returned error", error); - return error; - } - - /* Serialize main items */ - error = file_serialize_list(&serialized, - FILE_SER_NEW, - FILE_ITEM_REF, - ctx->config.set, - ctx->config.outmode, - ctx->config.main_fmt_cfg); - if (error) { - TRACE_ERROR_NUMBER("Failed to serialize main set", error); - col_destroy_collection(leftovers); - return error; - } - - if (ctx->config.use_leftovers) { - /* Do we have to jam leftovers? */ - if (ctx->config.jam_leftovers) { - /* Serialise leftovers into one field */ - error = file_serialize_list(&serialized_lo, - FILE_SER_NEW, - FILE_ITEM_REF, - leftovers, - ctx->config.mode_leftovers, - ctx->config.lo_fmt_cfg); - if (error) { - TRACE_ERROR_NUMBER("Failed to serialize main set", error); - col_destroy_collection(leftovers); - elapi_free_serialized_data(serialized); - return error; - } - - /* Check if we go anything */ - if (serialized_lo->length) { - /* Append leftovers item */ - error = file_serialize_item(serialized, - COL_TYPE_STRING, - serialized_lo->length + 1, - serialized_lo->buffer, - ctx->config.outmode, - ctx->config.main_fmt_cfg); - } - else { - /* Put empty item */ - error = file_serialize_item(serialized, - COL_TYPE_BINARY, - 0, - NULL, - ctx->config.outmode, - ctx->config.main_fmt_cfg); - } - if (error) { - TRACE_ERROR_NUMBER("Failed to serialize main set", error); - col_destroy_collection(leftovers); - elapi_free_serialized_data(serialized); - elapi_free_serialized_data(serialized_lo); - return error; - } - - /* Done with the jammed leftovers */ - elapi_free_serialized_data(serialized_lo); - } - else { - /* Leftovers are added as normal fields */ - error = file_serialize_list(&serialized, - FILE_SER_APPEND, - FILE_ITEM_REF, - leftovers, - ctx->config.outmode, - ctx->config.main_fmt_cfg); - if (error) { - TRACE_ERROR_NUMBER("Failed to serialize main set", error); - col_destroy_collection(leftovers); - elapi_free_serialized_data(serialized); - return error; - } - } - /* Do not need leftovers */ - col_destroy_collection(leftovers); - } - } - else { - /* No set is defined - the whole event is processed */ - error = file_serialize_list(&serialized, - FILE_SER_NEW, - FILE_ITEM_DIRECT, - event, - ctx->config.outmode, - ctx->config.main_fmt_cfg); - if (error) { - TRACE_ERROR_NUMBER("Failed to serialize event", error); - return error; - } - } - - *out_data = serialized; - - TRACE_FLOW_STRING("file_prep_data", "Exit"); - return error; - -} diff --git a/common/elapi/providers/file/file_util.h b/common/elapi/providers/file/file_util.h deleted file mode 100644 index f4c0e4bf..00000000 --- a/common/elapi/providers/file/file_util.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - ELAPI - - Header for file provider utility functions. - - 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/>. -*/ - -#ifndef FILE_UTIL_H -#define FILE_UTIL_H - -#include "file_provider.h" -#include "elapi_basic.h" -#include "collection.h" - -/* Sepcific format related includes */ -#include "file_fmt_csv.h" - -/* Leftovers' class and name */ -#define FILE_LO_NAME "lo" -#define FILE_LO_CLASS 20300 - -/* Allocate a new one or add to existing */ -#define FILE_SER_NEW 0 -#define FILE_SER_APPEND 1 - -/* Denotes how data is referenced */ -#define FILE_ITEM_DIRECT 0 /* Data is in the collection */ -#define FILE_ITEM_REF 1 /* Collection contains references */ - - -/* Function to prepare data for logging */ -int file_prep_data(struct elapi_data_out **out_data, - struct file_prvdr_ctx *ctx, - struct collection_item *event); - -#endif |