diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 16:28:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 16:28:20 +0000 |
commit | dcc721a95bef6f0d8e6d8775b8efe33e5aecd562 (patch) | |
tree | 66a2774cd0ee294d019efd71d2544c70f42b2842 /contrib | |
parent | Initial commit. (diff) | |
download | rsyslog-dcc721a95bef6f0d8e6d8775b8efe33e5aecd562.tar.xz rsyslog-dcc721a95bef6f0d8e6d8775b8efe33e5aecd562.zip |
Adding upstream version 8.2402.0.upstream/8.2402.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'contrib')
126 files changed, 56031 insertions, 0 deletions
diff --git a/contrib/README b/contrib/README new file mode 100644 index 0000000..7de58a8 --- /dev/null +++ b/contrib/README @@ -0,0 +1,12 @@ +This directory contains a number of possibly useful things that do not +directly relate to rsyslog. They are not actively supported, but as +I said often helpful. Use them with some care, as they may be outdated +in respect to the current release of rsyslog. + +At least some of this stuff has been found by our users and been +included after a brief check and possibly an adaptation. If you have +something useful you would like to see in contrib, just drop us a +note (see https://www.rsyslog.com for how to do that at the time your +are reading this document). + +rgerhards, 2007-08-08 diff --git a/contrib/ffaup/Makefile.am b/contrib/ffaup/Makefile.am new file mode 100644 index 0000000..8493662 --- /dev/null +++ b/contrib/ffaup/Makefile.am @@ -0,0 +1,8 @@ +# +# ffaup support +# +pkglib_LTLIBRARIES = ffaup.la +ffaup_la_SOURCES = ffaup.c +ffaup_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +ffaup_la_LDFLAGS = -module -avoid-version +ffaup_la_LIBADD = $(FAUP_LIBS) diff --git a/contrib/ffaup/Makefile.in b/contrib/ffaup/Makefile.in new file mode 100644 index 0000000..42d5b20 --- /dev/null +++ b/contrib/ffaup/Makefile.in @@ -0,0 +1,801 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/ffaup +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +ffaup_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_ffaup_la_OBJECTS = ffaup_la-ffaup.lo +ffaup_la_OBJECTS = $(am_ffaup_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +ffaup_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(ffaup_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/ffaup_la-ffaup.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(ffaup_la_SOURCES) +DIST_SOURCES = $(ffaup_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# +# ffaup support +# +pkglib_LTLIBRARIES = ffaup.la +ffaup_la_SOURCES = ffaup.c +ffaup_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +ffaup_la_LDFLAGS = -module -avoid-version +ffaup_la_LIBADD = $(FAUP_LIBS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/ffaup/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/ffaup/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +ffaup.la: $(ffaup_la_OBJECTS) $(ffaup_la_DEPENDENCIES) $(EXTRA_ffaup_la_DEPENDENCIES) + $(AM_V_CCLD)$(ffaup_la_LINK) -rpath $(pkglibdir) $(ffaup_la_OBJECTS) $(ffaup_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffaup_la-ffaup.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +ffaup_la-ffaup.lo: ffaup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ffaup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ffaup_la-ffaup.lo -MD -MP -MF $(DEPDIR)/ffaup_la-ffaup.Tpo -c -o ffaup_la-ffaup.lo `test -f 'ffaup.c' || echo '$(srcdir)/'`ffaup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ffaup_la-ffaup.Tpo $(DEPDIR)/ffaup_la-ffaup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ffaup.c' object='ffaup_la-ffaup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ffaup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ffaup_la-ffaup.lo `test -f 'ffaup.c' || echo '$(srcdir)/'`ffaup.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/ffaup_la-ffaup.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/ffaup_la-ffaup.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/ffaup/ffaup.c b/contrib/ffaup/ffaup.c new file mode 100644 index 0000000..c75ff7b --- /dev/null +++ b/contrib/ffaup/ffaup.c @@ -0,0 +1,395 @@ +/* ffaup.c + * This is a function module for URL parsing. + * + * File begun on 2021/10/23 by TBertin + * + * Copyright 2007-2021 Theo Bertin for Advens + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> +#include <stddef.h> +#ifndef _AIX +#include <typedefs.h> +#endif +#include <sys/types.h> +#include <string.h> +#include <faup/faup.h> +#include <faup/decode.h> +#include <faup/options.h> +#include <faup/output.h> + +#include "config.h" +#include "rsyslog.h" +#include "parserif.h" +#include "module-template.h" +#include "rainerscript.h" + + + +MODULE_TYPE_FUNCTION +MODULE_TYPE_NOKEEP +DEF_FMOD_STATIC_DATA + +faup_options_t *glbOptions = NULL; + +enum _faup_parse_type_t { + FAUP_PARSE_ALL, + FAUP_PARSE_SCHEME, + FAUP_PARSE_CREDENTIAL, + FAUP_PARSE_SUBDOMAIN, + FAUP_PARSE_DOMAIN, + FAUP_PARSE_DOMAIN_WITHOUT_TLD, + FAUP_PARSE_HOST, + FAUP_PARSE_TLD, + FAUP_PARSE_PORT, + FAUP_PARSE_RESOURCE_PATH, + FAUP_PARSE_QUERY_STRING, + FAUP_PARSE_FRAGMENT +}; +typedef enum _faup_parse_type_t faup_parse_type_t; + + +static inline sbool check_param_count_faup(unsigned short nParams) { + return nParams != 1; +} + + +static void ATTR_NONNULL() +do_faup_parse(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti, const faup_parse_type_t parse_type) { + struct svar srcVal; + int bMustFree; + cnfexprEval(func->expr[0], &srcVal, usrptr, pWti); + char *url = (char*) var2CString(&srcVal, &bMustFree); + + /* + We use the faup_handler_t struct directly instead of calling faup_init to avoid overhead and useless + allocations. Using one handler is not possible as the lib is not thread-safe and thread-locale solutions + still cause some issues. + If the faup_init function changes significantly in the future, it may cause issue. + (Validated with faup v1.5 and faup-master fecf768603e713bc903c56c8df0870fae14e3f93) + */ + faup_handler_t fh = {0}; + fh.options = glbOptions; + + // default, return 0 + ret->datatype = 'N'; + ret->d.n = 0; + + if(!faup_decode(&fh, url, strlen(url))) { + parser_errmsg("faup: could not parse the value\n"); + // No returned error code, so the reason doesn't matter + FINALIZE; + } + + switch(parse_type) { + case FAUP_PARSE_ALL: + ret->datatype = 'J'; + ret->d.json = json_object_new_object(); + json_object_object_add( + ret->d.json, + "scheme", + json_object_new_string_len( + url + faup_get_scheme_pos(&fh), + faup_get_scheme_size(&fh))); + json_object_object_add( + ret->d.json, + "credential", + json_object_new_string_len( + url + faup_get_credential_pos(&fh), + faup_get_credential_size(&fh))); + json_object_object_add( + ret->d.json, + "subdomain", + json_object_new_string_len( + url + faup_get_subdomain_pos(&fh), + faup_get_subdomain_size(&fh))); + json_object_object_add( + ret->d.json, + "domain", + json_object_new_string_len( + url + faup_get_domain_pos(&fh), + faup_get_domain_size(&fh))); + json_object_object_add( + ret->d.json, + "domain_without_tld", + json_object_new_string_len( + url + faup_get_domain_without_tld_pos(&fh), + faup_get_domain_without_tld_size(&fh))); + json_object_object_add( + ret->d.json, + "host", + json_object_new_string_len( + url + faup_get_host_pos(&fh), + faup_get_host_size(&fh))); + json_object_object_add( + ret->d.json, + "tld", + json_object_new_string_len( + url + faup_get_tld_pos(&fh), + faup_get_tld_size(&fh))); + json_object_object_add( + ret->d.json, + "port", + json_object_new_string_len( + url + faup_get_port_pos(&fh), + faup_get_port_size(&fh))); + json_object_object_add( + ret->d.json, + "resource_path", + json_object_new_string_len( + url + faup_get_resource_path_pos(&fh), + faup_get_resource_path_size(&fh))); + json_object_object_add( + ret->d.json, + "query_string", + json_object_new_string_len( + url + faup_get_query_string_pos(&fh), + faup_get_query_string_size(&fh))); + json_object_object_add( + ret->d.json, + "fragment", + json_object_new_string_len( + url + faup_get_fragment_pos(&fh), + faup_get_fragment_size(&fh))); + break; + case FAUP_PARSE_SCHEME: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_scheme_pos(&fh), faup_get_scheme_size(&fh)); + break; + case FAUP_PARSE_CREDENTIAL: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_credential_pos(&fh), faup_get_credential_size(&fh)); + break; + case FAUP_PARSE_SUBDOMAIN: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_subdomain_pos(&fh), faup_get_subdomain_size(&fh)); + break; + case FAUP_PARSE_DOMAIN: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_domain_pos(&fh), faup_get_domain_size(&fh)); + break; + case FAUP_PARSE_DOMAIN_WITHOUT_TLD: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_domain_without_tld_pos(&fh), faup_get_domain_without_tld_size(&fh)); + break; + case FAUP_PARSE_HOST: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_host_pos(&fh), faup_get_host_size(&fh)); + break; + case FAUP_PARSE_TLD: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_tld_pos(&fh), faup_get_tld_size(&fh)); + break; + case FAUP_PARSE_PORT: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_port_pos(&fh), faup_get_port_size(&fh)); + break; + case FAUP_PARSE_RESOURCE_PATH: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_resource_path_pos(&fh), faup_get_resource_path_size(&fh)); + break; + case FAUP_PARSE_QUERY_STRING: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_query_string_pos(&fh), faup_get_query_string_size(&fh)); + break; + case FAUP_PARSE_FRAGMENT: + ret->datatype = 'S'; + ret->d.estr = es_newStrFromCStr( + url + faup_get_fragment_pos(&fh), faup_get_fragment_size(&fh)); + break; + } + +finalize_it: + if(bMustFree) { + free(url); + } + varFreeMembers(&srcVal); +} + + +static void ATTR_NONNULL() +do_faup_parse_full(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_ALL); +} + + +static void ATTR_NONNULL() +do_faup_parse_scheme(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_SCHEME); +} + + +static void ATTR_NONNULL() +do_faup_parse_credential(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_CREDENTIAL); +} + + +static void ATTR_NONNULL() +do_faup_parse_subdomain(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_SUBDOMAIN); +} + + +static void ATTR_NONNULL() +do_faup_parse_domain(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_DOMAIN); +} + + +static void ATTR_NONNULL() +do_faup_parse_domain_without_tld(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_DOMAIN_WITHOUT_TLD); +} + + +static void ATTR_NONNULL() +do_faup_parse_host(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_HOST); +} + + +static void ATTR_NONNULL() +do_faup_parse_tld(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_TLD); +} + + +static void ATTR_NONNULL() +do_faup_parse_port(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_PORT); +} + + +static void ATTR_NONNULL() +do_faup_parse_resource_path(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_RESOURCE_PATH); +} + + +static void ATTR_NONNULL() +do_faup_parse_query_string(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_QUERY_STRING); +} + + +static void ATTR_NONNULL() +do_faup_parse_fragment(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_FRAGMENT); +} + + +static rsRetVal ATTR_NONNULL(1) +initFunc_faup_parse(struct cnffunc *const func) +{ + DEFiRet; + + // Rsyslog cannot free the funcdata object, + // a library-specific freeing function will be used during destruction + func->destructable_funcdata = 0; + if(check_param_count_faup(func->nParams)) { + parser_errmsg("ffaup: ffaup(key) insufficient params.\n"); + ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); + } + +finalize_it: + RETiRet; +} + + +static struct scriptFunct functions[] = { + {"faup", 1, 1, do_faup_parse_full, initFunc_faup_parse, NULL}, + {"faup_scheme", 1, 1, do_faup_parse_scheme, initFunc_faup_parse, NULL}, + {"faup_credential", 1, 1, do_faup_parse_credential, initFunc_faup_parse, NULL}, + {"faup_subdomain", 1, 1, do_faup_parse_subdomain, initFunc_faup_parse, NULL}, + {"faup_domain", 1, 1, do_faup_parse_domain, initFunc_faup_parse, NULL}, + {"faup_domain_without_tld", 1, 1, do_faup_parse_domain_without_tld, initFunc_faup_parse, NULL}, + {"faup_host", 1, 1, do_faup_parse_host, initFunc_faup_parse, NULL}, + {"faup_tld", 1, 1, do_faup_parse_tld, initFunc_faup_parse, NULL}, + {"faup_port", 1, 1, do_faup_parse_port, initFunc_faup_parse, NULL}, + {"faup_resource_path", 1, 1, do_faup_parse_resource_path, initFunc_faup_parse, NULL}, + {"faup_query_string", 1, 1, do_faup_parse_query_string, initFunc_faup_parse, NULL}, + {"faup_fragment", 1, 1, do_faup_parse_fragment, initFunc_faup_parse, NULL}, + {NULL, 0, 0, NULL, NULL, NULL} //last element to check end of array +}; + +BEGINgetFunctArray +CODESTARTgetFunctArray + dbgprintf("Faup: ffaup\n"); + *version = 1; + *functArray = functions; +ENDgetFunctArray + + +BEGINmodExit +CODESTARTmodExit + dbgprintf("ffaup: freeing options\n"); + if(glbOptions){ + faup_options_free(glbOptions); + glbOptions = NULL; + } +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_FMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ + + dbgprintf("ffaup: initializing options\n"); + glbOptions = faup_options_new(); + if(!glbOptions) { + parser_errmsg("ffaup: could not initialize options\n"); + ABORT_FINALIZE(RS_RET_FAUP_INIT_OPTIONS_FAILED); + } + // Don't generate a string output, and don't load LUA modules + // This is useful only for the faup executable + glbOptions->output = FAUP_OUTPUT_NONE; + glbOptions->exec_modules = FAUP_MODULES_NOEXEC; +CODEmodInit_QueryRegCFSLineHdlr + dbgprintf("rsyslog ffaup init called, compiled with version %s\n", VERSION); +ENDmodInit diff --git a/contrib/fmhash/Makefile.am b/contrib/fmhash/Makefile.am new file mode 100644 index 0000000..d16e121 --- /dev/null +++ b/contrib/fmhash/Makefile.am @@ -0,0 +1,8 @@ +# +# fmhash support +# +pkglib_LTLIBRARIES = fmhash.la +fmhash_la_SOURCES = fmhash.c +fmhash_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +fmhash_la_LDFLAGS = -module -avoid-version +fmhash_la_LIBADD = $(HASH_XXHASH_LIBS) diff --git a/contrib/fmhash/Makefile.in b/contrib/fmhash/Makefile.in new file mode 100644 index 0000000..892be4b --- /dev/null +++ b/contrib/fmhash/Makefile.in @@ -0,0 +1,801 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/fmhash +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +fmhash_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_fmhash_la_OBJECTS = fmhash_la-fmhash.lo +fmhash_la_OBJECTS = $(am_fmhash_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +fmhash_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(fmhash_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fmhash_la-fmhash.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(fmhash_la_SOURCES) +DIST_SOURCES = $(fmhash_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# +# fmhash support +# +pkglib_LTLIBRARIES = fmhash.la +fmhash_la_SOURCES = fmhash.c +fmhash_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +fmhash_la_LDFLAGS = -module -avoid-version +fmhash_la_LIBADD = $(HASH_XXHASH_LIBS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/fmhash/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/fmhash/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +fmhash.la: $(fmhash_la_OBJECTS) $(fmhash_la_DEPENDENCIES) $(EXTRA_fmhash_la_DEPENDENCIES) + $(AM_V_CCLD)$(fmhash_la_LINK) -rpath $(pkglibdir) $(fmhash_la_OBJECTS) $(fmhash_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmhash_la-fmhash.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +fmhash_la-fmhash.lo: fmhash.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmhash_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fmhash_la-fmhash.lo -MD -MP -MF $(DEPDIR)/fmhash_la-fmhash.Tpo -c -o fmhash_la-fmhash.lo `test -f 'fmhash.c' || echo '$(srcdir)/'`fmhash.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fmhash_la-fmhash.Tpo $(DEPDIR)/fmhash_la-fmhash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fmhash.c' object='fmhash_la-fmhash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmhash_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fmhash_la-fmhash.lo `test -f 'fmhash.c' || echo '$(srcdir)/'`fmhash.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fmhash_la-fmhash.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/fmhash_la-fmhash.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/fmhash/fmhash.c b/contrib/fmhash/fmhash.c new file mode 100644 index 0000000..224b824 --- /dev/null +++ b/contrib/fmhash/fmhash.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2018, Harshvardhan Shrivastava + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include <stdint.h> +#include <stddef.h> +#ifndef _AIX +#include <typedefs.h> +#endif +#include <sys/types.h> +#include <string.h> +#ifdef USE_HASH_XXHASH +# include <xxhash.h> +#endif + +#include "rsyslog.h" +#include "parserif.h" +#include "module-template.h" +#include "rainerscript.h" + + + +MODULE_TYPE_FUNCTION +MODULE_TYPE_NOKEEP +DEF_FMOD_STATIC_DATA + +typedef uint64_t hash_t; +typedef uint32_t seed_t; +typedef struct hash_context_s hash_context_t; + +typedef hash_t (*hash_impl)(const void*, size_t, seed_t); + +typedef rsRetVal (*hash_wrapper_2)(struct svar *__restrict__ const + , struct svar *__restrict__ const, hash_context_t*, hash_t*); +typedef rsRetVal (*hash_wrapper_3)(struct svar *__restrict__ const, struct svar *__restrict__ const + , struct svar *__restrict__ const, hash_context_t*, hash_t*); + +struct hash_context_s { + hash_impl hashXX; + hash_wrapper_2 hash_wrapper_1_2; + hash_wrapper_3 hash_wrapper_2_3; +}; + +/* + * Fowler–Noll–Vo hash 32 bit + * http://www.isthe.com/chongo/src/fnv/hash_32.c + */ +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wunknown-attributes" +#endif +static hash_t +#if defined(__clang__) +__attribute__((no_sanitize("unsigned-integer-overflow"))) +#endif +fnv_32(const void* input, size_t len, seed_t seed) { + unsigned char *bp = (unsigned char *)input; /* start of buffer */ + + /* + * FNV-1 hash each octet in the buffer + */ + size_t i; + for (i = 0; i < len; i++) { + /* multiply by the 32 bit FNV magic prime mod 2^32 */ + seed += (seed<<1) + (seed<<4) + (seed<<7) + (seed<<8) + (seed<<24); + + /* xor the bottom with the current octet */ + seed ^= (seed_t)*bp++; + } + + /* return our new hash value */ + return seed; +} + + +/* + * Modified Bernstein + * http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx + */ +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wunknown-attributes" +#endif +static hash_t +#if defined(__clang__) +__attribute__((no_sanitize("unsigned-integer-overflow"))) +#endif +djb_hash(const void* input, size_t len, seed_t seed) { + const char *p = input; + hash_t hash = 5381; + size_t i; + for (i = 0; i < len; i++) { + hash = 33 * hash ^ p[i]; + } + + return hash + seed; +} + +/*Get 32 bit hash for input*/ +static hash_t +hash32(const void* input, size_t len, seed_t seed) { + hash_t xhash = 0; +#ifdef USE_HASH_XXHASH + xhash = XXH32(input, len, seed); +#else + xhash = fnv_32(input, len, seed); +#endif + return xhash; +} + +/*Get 64 bit hash for input*/ +static hash_t +hash64(const void* input, size_t len, seed_t seed) { + hash_t xhash = 0; +#ifdef USE_HASH_XXHASH + xhash = XXH64(input, len, seed); +#else + xhash = djb_hash(input, len, seed); +#endif + return xhash; +} + +static rsRetVal +hash_wrapper2(struct svar *__restrict__ const sourceVal + , struct svar *__restrict__ const seedVal, hash_context_t* hcontext, hash_t* xhash) { + DEFiRet; + int freeHashStr = 0, success = 0; + char *hashStr = NULL; + seed_t seed = 0; + if(seedVal) { + seed = var2Number(seedVal, &success); + if (!success) { + parser_warnmsg("fmhash: hashXX(string, seed) didn't get a valid 'seed' limit" + ", defaulting hash value to 0"); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + } + + hashStr = (char*)var2CString(sourceVal, &freeHashStr); + size_t len = strlen(hashStr); + (*xhash) = hcontext->hashXX(hashStr, len, seed); + DBGPRINTF("fmhash: hashXX generated hash %" PRIu64 " for string(%.*s)" + , (*xhash), (int)len, hashStr); +finalize_it: + if (freeHashStr) { + free(hashStr); + } + RETiRet; +} + +static rsRetVal +hash_wrapper3(struct svar *__restrict__ const sourceVal, struct svar *__restrict__ const modVal + , struct svar *__restrict__ const seedVal, hash_context_t* hcontext, hash_t* xhash) { + + DEFiRet; + int success = 0; + hash_t mod = var2Number(modVal, &success); + if (! success) { + parser_warnmsg("fmhash: hashXXmod(string, mod)/hash64mod(string, mod, seed) didn't" + " get a valid 'mod' limit, defaulting hash value to 0"); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + if(mod == 0) { + parser_warnmsg("fmhash: hashXXmod(string, mod)/hash64mod(string, mod, seed) invalid" + ", 'mod' is zero, , defaulting hash value to 0"); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + + CHKiRet((hcontext->hash_wrapper_1_2(sourceVal, seedVal, hcontext, xhash))); + if(mod != 0) { + (*xhash) = (*xhash) % mod; + } + DBGPRINTF("fmhash: hashXXmod generated hash-mod %" PRIu64 ".", (*xhash)); +finalize_it: + RETiRet; +} + +static void +init_hash32_context(hash_context_t* hash32_context) { + hash32_context->hashXX = hash32; + hash32_context->hash_wrapper_1_2 = hash_wrapper2; + hash32_context->hash_wrapper_2_3 = hash_wrapper3; +}; + +static void +init_hash64_context(hash_context_t* hash64_context) { + hash64_context->hashXX = hash64; + hash64_context->hash_wrapper_1_2 = hash_wrapper2; + hash64_context->hash_wrapper_2_3 = hash_wrapper3; +}; + +static void ATTR_NONNULL() +fmHashXX(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + DEFiRet; + struct svar hashStrVal; + struct svar seedVal; + hash_context_t* hcontext = NULL; + hash_t xhash = 0; + cnfexprEval(func->expr[0], &hashStrVal, usrptr, pWti); + if(func->nParams == 2) cnfexprEval(func->expr[1], &seedVal, usrptr, pWti); + ret->d.n = 0; + ret->datatype = 'N'; + hcontext = (hash_context_t*) func->funcdata; + CHKiRet((hcontext->hash_wrapper_1_2(&hashStrVal + , (func->nParams == 2 ? &seedVal : NULL) + , hcontext, &xhash))); + ret->d.n = xhash; +finalize_it: + varFreeMembers(&hashStrVal); + if(func->nParams == 2) varFreeMembers(&seedVal); +} + +static void ATTR_NONNULL() +fmHashXXmod(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { + + DEFiRet; + struct svar hashStrVal; + struct svar modVal; + struct svar seedVal; + hash_context_t* hcontext = NULL; + hash_t xhash = 0; + cnfexprEval(func->expr[0], &hashStrVal, usrptr, pWti); + cnfexprEval(func->expr[1], &modVal, usrptr, pWti); + if(func->nParams == 3) cnfexprEval(func->expr[2], &seedVal, usrptr, pWti); + ret->d.n = 0; + ret->datatype = 'N'; + hcontext = (hash_context_t*) func->funcdata; + CHKiRet((hcontext->hash_wrapper_2_3(&hashStrVal + , &modVal, func->nParams > 2 ? &seedVal : NULL + , hcontext, &xhash))); + ret->d.n = xhash; +finalize_it: + varFreeMembers(&hashStrVal); + varFreeMembers(&modVal); + if(func->nParams == 3) varFreeMembers(&seedVal); +} + +static inline sbool check_param_count_hash(unsigned short nParams) { + return (nParams != 1 && nParams != 2); +} + +static inline sbool check_param_count_hashmod(unsigned short nParams) { + return (nParams != 2 && nParams != 3); +} + +static rsRetVal ATTR_NONNULL(1) +init_fmHash64(struct cnffunc *const func) +{ + DEFiRet; + hash_context_t *hash_context = NULL; + if(check_param_count_hash(func->nParams)) { + parser_errmsg("fmhash: hash64(string) / hash64(string, seed)" + " insufficient params.\n"); + ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); + } + func->destructable_funcdata = 1; + CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); + init_hash64_context(hash_context); + func->funcdata = (void*)hash_context; + +finalize_it: + RETiRet; +} + +static rsRetVal ATTR_NONNULL(1) +init_fmHash64mod(struct cnffunc *const func) +{ + DEFiRet; + hash_context_t *hash_context = NULL; + if(check_param_count_hashmod(func->nParams)) { + parser_errmsg("fmhash: hash64mod(string, mod)/hash64mod(string, mod, seed)" + " insufficient params.\n"); + ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); + } + func->destructable_funcdata = 1; + CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); + init_hash64_context(hash_context); + func->funcdata = (void*)hash_context; +finalize_it: + RETiRet; +} + +static rsRetVal ATTR_NONNULL(1) +init_fmHash32(struct cnffunc *const func) +{ + DEFiRet; + hash_context_t *hash_context = NULL; + if(check_param_count_hash(func->nParams)) { + parser_errmsg("fmhash: hash32(string) / hash32(string, seed)" + " insufficient params.\n"); + ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); + } + func->destructable_funcdata = 1; + CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); + init_hash32_context(hash_context); + func->funcdata = (void*)hash_context; + +finalize_it: + RETiRet; +} + +static rsRetVal ATTR_NONNULL(1) +init_fmHash32mod(struct cnffunc *const func) +{ + DEFiRet; + hash_context_t *hash_context = NULL; + if(check_param_count_hashmod(func->nParams)) { + parser_errmsg("fmhash: hash32mod(string, mod)/hash32mod(string, mod, seed)" + " insufficient params.\n"); + ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); + } + func->destructable_funcdata = 1; + CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); + init_hash32_context(hash_context); + func->funcdata = (void*)hash_context; +finalize_it: + RETiRet; +} + + +static struct scriptFunct functions[] = { + {"hash64", 1, 2, fmHashXX, init_fmHash64, NULL}, + {"hash64mod", 2, 3, fmHashXXmod, init_fmHash64mod, NULL}, + {"hash32", 1, 2, fmHashXX, init_fmHash32, NULL}, + {"hash32mod", 2, 3, fmHashXXmod, init_fmHash32mod, NULL}, + {NULL, 0, 0, NULL, NULL, NULL} //last element to check end of array +}; + + +BEGINgetFunctArray +CODESTARTgetFunctArray + dbgprintf("Hash: fmhhash\n"); + *version = 1; + *functArray = functions; +ENDgetFunctArray + + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_FMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + dbgprintf("rsyslog fmhash init called, compiled with version %s\n", VERSION); +ENDmodInit diff --git a/contrib/fmunflatten/Makefile.am b/contrib/fmunflatten/Makefile.am new file mode 100644 index 0000000..b3d27e4 --- /dev/null +++ b/contrib/fmunflatten/Makefile.am @@ -0,0 +1,5 @@ +pkglib_LTLIBRARIES = fmunflatten.la +fmunflatten_la_SOURCES = fmunflatten.c +fmunflatten_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(JSON_C_CFLAGS) +fmunflatten_la_LDFLAGS = -module -avoid-version +fmunflatten_la_LIBADD = $(JSON_C_LIBS) diff --git a/contrib/fmunflatten/Makefile.in b/contrib/fmunflatten/Makefile.in new file mode 100644 index 0000000..366f145 --- /dev/null +++ b/contrib/fmunflatten/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/fmunflatten +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +fmunflatten_la_DEPENDENCIES = +am_fmunflatten_la_OBJECTS = fmunflatten_la-fmunflatten.lo +fmunflatten_la_OBJECTS = $(am_fmunflatten_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +fmunflatten_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(fmunflatten_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(fmunflatten_la_SOURCES) +DIST_SOURCES = $(fmunflatten_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = fmunflatten.la +fmunflatten_la_SOURCES = fmunflatten.c +fmunflatten_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(JSON_C_CFLAGS) +fmunflatten_la_LDFLAGS = -module -avoid-version +fmunflatten_la_LIBADD = $(JSON_C_LIBS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/fmunflatten/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/fmunflatten/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +fmunflatten.la: $(fmunflatten_la_OBJECTS) $(fmunflatten_la_DEPENDENCIES) $(EXTRA_fmunflatten_la_DEPENDENCIES) + $(AM_V_CCLD)$(fmunflatten_la_LINK) -rpath $(pkglibdir) $(fmunflatten_la_OBJECTS) $(fmunflatten_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +fmunflatten_la-fmunflatten.lo: fmunflatten.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmunflatten_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fmunflatten_la-fmunflatten.lo -MD -MP -MF $(DEPDIR)/fmunflatten_la-fmunflatten.Tpo -c -o fmunflatten_la-fmunflatten.lo `test -f 'fmunflatten.c' || echo '$(srcdir)/'`fmunflatten.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fmunflatten_la-fmunflatten.Tpo $(DEPDIR)/fmunflatten_la-fmunflatten.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fmunflatten.c' object='fmunflatten_la-fmunflatten.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmunflatten_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fmunflatten_la-fmunflatten.lo `test -f 'fmunflatten.c' || echo '$(srcdir)/'`fmunflatten.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/fmunflatten/fmunflatten.c b/contrib/fmunflatten/fmunflatten.c new file mode 100644 index 0000000..f1e4e69 --- /dev/null +++ b/contrib/fmunflatten/fmunflatten.c @@ -0,0 +1,243 @@ +/* + * This is a function module providing ability to unflatten a JSON tree. + * + * Copyright 2020 Julien Thomas < jthomas @ zenetys.com > + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" + +#include <stdint.h> +#include <stddef.h> +#ifndef _AIX +#include <typedefs.h> +#endif +#include <sys/types.h> +#include <string.h> + +#include "rsyslog.h" + +#include "errmsg.h" +#include "msg.h" +#include "parserif.h" +#include "module-template.h" +#include "rainerscript.h" +#include "wti.h" + +#define FMUNFLATTEN_KBUFLEN 256 +#define _jso_type(x) json_type_to_name(json_object_get_type(x)) + +MODULE_TYPE_FUNCTION +MODULE_TYPE_NOKEEP +DEF_FMOD_STATIC_DATA + +struct unflatten_ctx { + char *kbuf; + size_t kbuf_len; + char delim; +}; + +/* forward declarations */ +void unflatten_add(struct unflatten_ctx *ctx, struct json_object *dst, const char *key, struct json_object *value); +void unflatten(struct unflatten_ctx *ctx, struct json_object *src, struct json_object *dst); + +void unflatten_add(struct unflatten_ctx *ctx, + struct json_object *dst, + const char *key, + struct json_object *value) +{ + const char *p = key; + const char *q = p; + int depth = 0; + size_t klen; + struct json_object *o; + json_bool exists_already; + int create; + + while (1) { + while (*q != ctx->delim && *q != '\0') + q++; + klen = q - p; + if (klen + 1 > ctx->kbuf_len) { + DBGPRINTF("warning: flat key \"%.20s...\" truncated at depth #%d, buffer too " + "small (max %zd)\n", key, depth, ctx->kbuf_len); + klen = ctx->kbuf_len - 1; + } + memcpy(ctx->kbuf, p, klen); + ctx->kbuf[klen] = '\0'; + exists_already = json_object_object_get_ex(dst, ctx->kbuf, &o); + + if (*q == ctx->delim) { + if (!exists_already) + create = 1; + else if (json_object_is_type(o, json_type_object)) + create = 0; + else { + DBGPRINTF("warning: while processing flat key \"%s\" at depth #%d (intermediate " + "node), overriding existing value of type %s by an object\n", key, depth, + _jso_type(o)); + json_object_object_del(dst, ctx->kbuf); + create = 1; + } + if (create) { + o = json_object_new_object(); + json_object_object_add(dst, ctx->kbuf, o); + } + dst = o; + p = q + 1; + q = p; + depth++; + } + else if (*q == '\0') { + if (json_object_is_type(value, json_type_object)) { + if (exists_already) { + if (!json_object_is_type(o, json_type_object)) { + DBGPRINTF("warning: while processing flat key \"%s\" at depth #%d " + "(final node), overriding existing value of type %s by an " + "object\n", key, depth, _jso_type(o)); + json_object_object_del(dst, ctx->kbuf); + o = json_object_new_object(); + json_object_object_add(dst, ctx->kbuf, o); + } + } + else { + o = json_object_new_object(); + json_object_object_add(dst, ctx->kbuf, o); + } + unflatten(ctx, value, o); + } + else { + if (exists_already) { + DBGPRINTF("warning: while processing flat key \"%s\" at depth #%d " + "(final node), overriding existing value\n", key, depth); + json_object_object_del(dst, ctx->kbuf); + } + o = jsonDeepCopy(value); + json_object_object_add(dst, ctx->kbuf, o); + } + break; + } + } +} + +void unflatten(struct unflatten_ctx *ctx, + struct json_object *src, + struct json_object *dst) +{ + struct json_object_iterator it = json_object_iter_begin(src); + struct json_object_iterator itEnd = json_object_iter_end(src); + const char *key; + struct json_object *value; + + while (!json_object_iter_equal(&it, &itEnd)) { + key = json_object_iter_peek_name(&it); + value = json_object_iter_peek_value(&it); + unflatten_add(ctx, dst, key, value); + json_object_iter_next(&it); + } +} + +static void ATTR_NONNULL() +doFunc_unflatten(struct cnffunc *__restrict__ const func, + struct svar *__restrict__ const ret, + void *__restrict__ const usrptr, + wti_t *__restrict__ const pWti) +{ + struct svar src_var; + struct svar delim_var; + + char kbuf[FMUNFLATTEN_KBUFLEN]; + struct unflatten_ctx ctx = { + .kbuf = kbuf, + .kbuf_len = sizeof(kbuf), + .delim = 0 + }; + + /* A dummy value of 0 (number) is returned by default. Callers should also + * call script_error() to check if this script function succeeded before + * using the value it returns. */ + ret->datatype = 'N'; + ret->d.n = 0; + wtiSetScriptErrno(pWti, RS_SCRIPT_EINVAL); + + cnfexprEval(func->expr[0], &src_var, usrptr, pWti); + cnfexprEval(func->expr[1], &delim_var, usrptr, pWti); + + /* Check argument 2 (delimiter character). */ + if (delim_var.datatype == 'S' && es_strlen(delim_var.d.estr) == 1) + ctx.delim = *es_getBufAddr(delim_var.d.estr); + else if (delim_var.datatype == 'N') + ctx.delim = delim_var.d.n; + if (ctx.delim == 0) { + LogError(0, RS_RET_INVALID_PARAMS, "unflatten: invalid argument 2 (delim), single character " + "required (as string or decimal charcode)"); + FINALIZE; + } + + /* Check argument 1 (source). Not logging an error avoids emitting logs for + * messages when $! was not touched. */ + if (src_var.datatype != 'J') { + DBGPRINTF("unsupported argument 1 (src) datatype %c\n", src_var.datatype); + FINALIZE; + } + + ret->datatype = 'J'; + if (json_object_is_type(src_var.d.json, json_type_object)) { + ret->d.json = json_object_new_object(); + unflatten(&ctx, src_var.d.json, ret->d.json); + } + else + ret->d.json = jsonDeepCopy(src_var.d.json); + wtiSetScriptErrno(pWti, RS_SCRIPT_EOK); + +finalize_it: + varFreeMembers(&src_var); + varFreeMembers(&delim_var); +} + +static rsRetVal ATTR_NONNULL(1) +initFunc_unflatten(struct cnffunc *const func) +{ + DEFiRet; + func->destructable_funcdata = 0; + RETiRet; +} + +static struct scriptFunct functions[] = { + { "unflatten", 2, 2, doFunc_unflatten, initFunc_unflatten, NULL }, + { NULL, 0, 0, NULL, NULL, NULL } /* last element to check end of array */ +}; + +BEGINgetFunctArray +CODESTARTgetFunctArray + *version = 1; + *functArray = functions; +ENDgetFunctArray + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_FMOD_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + dbgprintf("rsyslog fmunflatten init called, compiled with version %s\n", VERSION); +ENDmodInit diff --git a/contrib/gnutls/ca.pem b/contrib/gnutls/ca.pem new file mode 100644 index 0000000..6324c7d --- /dev/null +++ b/contrib/gnutls/ca.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYjCCAc2gAwIBAgIBATALBgkqhkiG9w0BAQUwWDELMAkGA1UEBhMCREUxHTAb +BgNVBAoTFHJzeXNsb2cgdGVzdCByb290IENBMQswCQYDVQQLEwJDQTEdMBsGA1UE +AxMUcnN5c2xvZy10ZXN0LXJvb3QtY2EwHhcNMDgwNTIwMTI1ODEyWhcNMTgwNTE4 +MTI1ODI0WjBYMQswCQYDVQQGEwJERTEdMBsGA1UEChMUcnN5c2xvZyB0ZXN0IHJv +b3QgQ0ExCzAJBgNVBAsTAkNBMR0wGwYDVQQDExRyc3lzbG9nLXRlc3Qtcm9vdC1j +YTCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGAw2s+V+WCK7jx9MLpDD4pO8SCqq6Q +nK/BptvKM+YeBrV9ud3lq6YgbpNmv3/wig43rqpolqk7PdDxTW/mdXPmM72oKr/N +Fc2cAyOEXK8JTWiqwc//V4qMAnKFfLOxr1dr7WRD0k4Tc8+BWJMQjL2zmGXiSGEF +YWYIFHLmnX4ZgyMCAwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8E +BQMDBwYAMB0GA1UdDgQWBBQzYQQgUm0YLNdarJnc2c1LxYVClDALBgkqhkiG9w0B +AQUDgYEAuGWtH7Jkpa0n/izqQ5ddDQP/LT6taivCwlpEYEU9aumpQPWWxtYywKaP +RfM1JTMLAiYd8MS7TJ8TYRvvR32Y02Y+OhXn11xERkWvBT2M9yzqX6hDfRueN7RT +fPWsfm/NBTVojzjaECcTFenZid7PC5JiFbcU6PSUMZ49/JPhxAo= +-----END CERTIFICATE----- diff --git a/contrib/gnutls/cert.pem b/contrib/gnutls/cert.pem new file mode 100644 index 0000000..6b5b13c --- /dev/null +++ b/contrib/gnutls/cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChjCCAfGgAwIBAgIBADALBgkqhkiG9w0BAQUwWDELMAkGA1UEBhMCREUxHTAb +BgNVBAoTFHJzeXNsb2cgdGVzdCByb290IENBMQswCQYDVQQLEwJDQTEdMBsGA1UE +AxMUcnN5c2xvZy10ZXN0LXJvb3QtY2EwHhcNMDgwNTIwMTMwNDE5WhcNMTgwNTE4 +MTMwNDI2WjA6MQswCQYDVQQGEwJERTEQMA4GA1UEChMHcnN5c2xvZzEZMBcGA1UE +CxMQdGVzdCBjZXJ0aWZpY2F0ZTCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGAxmHe +fztJgaGxFYEceiUg0hdMlRVWBqoZelJ8BeXTDnXcu/5F2HtM+l+QDyDaGjKlx+NI +K4rkj7d6Wd3AKPgOYS0VSDZe3a1xf9rRYzOthWTv7tYi4/LTqPXqN5lKE71dgrB/ +/gOmvV/1YD776FIxVGCSAT0hHwkFC3slmpJSwD8CAwEAAaOBhDCBgTAMBgNVHRMB +Af8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATASBgNVHREECzAJ +ggdyc3lzbG9nMB0GA1UdDgQWBBQYu6eC9UALvC+5K5VOnFRi5OC98TAfBgNVHSME +GDAWgBQzYQQgUm0YLNdarJnc2c1LxYVClDALBgkqhkiG9w0BAQUDgYEAXaymqsG9 +PNBhhWIRFvXCDMaDM71vUtgSFoNUbxIV607ua2HQosPPM4EHIda6N6hdBK1bMQoG +yqBwhvw0JVaVaO70Kbs2m2Ypk3YcpJtRqyp8q8+2y/w1Mk1QazFZC29aYgX2iNVf +X4/x38YEL7Gu5vqPrTn++agnV4ZXECKuvLQ= +-----END CERTIFICATE----- diff --git a/contrib/gnutls/key.pem b/contrib/gnutls/key.pem new file mode 100644 index 0000000..3ff507f --- /dev/null +++ b/contrib/gnutls/key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDGYd5/O0mBobEVgRx6JSDSF0yVFVYGqhl6UnwF5dMOddy7/kXY +e0z6X5APINoaMqXH40griuSPt3pZ3cAo+A5hLRVINl7drXF/2tFjM62FZO/u1iLj +8tOo9eo3mUoTvV2CsH/+A6a9X/VgPvvoUjFUYJIBPSEfCQULeyWaklLAPwIDAQAB +AoGARIwKqmHc+0rYenq7UUVE+vMMBjNyHyllVkvsCMmpzMRS+i5ZCf1I0vZ0O5X5 +ZrX7bH8PL+R1J2eZgjXKMR3NMZBuyKHewItD9t2rIC0eD/ITlwq3VybbaMsw666e +INxSmax+dS5CEcLevHHP3c+Q7S7QAFiWV43TdFUGXWJktIkCQQDPQ5WAZ+/Tvv0Q +vtRjXMeTVaw/bSuKNUeDzFkmGyePnFeCReNFtJLE9PFSQWcPuYcbZgU59JTfA5ac +Un+cHm31AkEA9Qek+q7PcJ+kON9E6SNodCZn6gLyHjnWrq4tf8pZO3NvoX2QiuD4 +rwF7KWjr6q1JzADpLtwXnuYEhyiLFjJA4wJAcElMCEnG2y+ASH8p7z7HfKGQdLg/ +O1wMB3JA5e0WLK5lllUogI4IaZ3N02NNY25+rLBDqpc/w+ZcxQnIypqNtQJATs9p +ofON5wSB1oUBbhckZo9fxuWxqEUkJsUA/2Q+9R843XE8h166vdc1HOmRT8bywHne +hmLl+gazmCFTMw1wzwJAHng+3zGUl4D8Ov3MPFD6hwYYK6/pEdtz/NUsCSazF7eK +XuuP+DXPHNhXOuF1A3tP74pfc/fC1uCUH2G5z3Fy0Q== +-----END RSA PRIVATE KEY----- diff --git a/contrib/imbatchreport/Makefile.am b/contrib/imbatchreport/Makefile.am new file mode 100644 index 0000000..a28f4f6 --- /dev/null +++ b/contrib/imbatchreport/Makefile.am @@ -0,0 +1,6 @@ +pkglib_LTLIBRARIES = imbatchreport.la + +imbatchreport_la_SOURCES = imbatchreport.c +imbatchreport_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +imbatchreport_la_LDFLAGS = -module -avoid-version +imbatchreport_la_LIBADD = diff --git a/contrib/imbatchreport/Makefile.in b/contrib/imbatchreport/Makefile.in new file mode 100644 index 0000000..db343f2 --- /dev/null +++ b/contrib/imbatchreport/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/imbatchreport +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +imbatchreport_la_DEPENDENCIES = +am_imbatchreport_la_OBJECTS = imbatchreport_la-imbatchreport.lo +imbatchreport_la_OBJECTS = $(am_imbatchreport_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +imbatchreport_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(imbatchreport_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imbatchreport_la_SOURCES) +DIST_SOURCES = $(imbatchreport_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = imbatchreport.la +imbatchreport_la_SOURCES = imbatchreport.c +imbatchreport_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +imbatchreport_la_LDFLAGS = -module -avoid-version +imbatchreport_la_LIBADD = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imbatchreport/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/imbatchreport/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +imbatchreport.la: $(imbatchreport_la_OBJECTS) $(imbatchreport_la_DEPENDENCIES) $(EXTRA_imbatchreport_la_DEPENDENCIES) + $(AM_V_CCLD)$(imbatchreport_la_LINK) -rpath $(pkglibdir) $(imbatchreport_la_OBJECTS) $(imbatchreport_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +imbatchreport_la-imbatchreport.lo: imbatchreport.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imbatchreport_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imbatchreport_la-imbatchreport.lo -MD -MP -MF $(DEPDIR)/imbatchreport_la-imbatchreport.Tpo -c -o imbatchreport_la-imbatchreport.lo `test -f 'imbatchreport.c' || echo '$(srcdir)/'`imbatchreport.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imbatchreport_la-imbatchreport.Tpo $(DEPDIR)/imbatchreport_la-imbatchreport.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imbatchreport.c' object='imbatchreport_la-imbatchreport.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imbatchreport_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imbatchreport_la-imbatchreport.lo `test -f 'imbatchreport.c' || echo '$(srcdir)/'`imbatchreport.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/imbatchreport/imbatchreport.c b/contrib/imbatchreport/imbatchreport.c new file mode 100644 index 0000000..be71ee7 --- /dev/null +++ b/contrib/imbatchreport/imbatchreport.c @@ -0,0 +1,1033 @@ +/* imbatchreport.c + * + * This is the input module for reading full text file data. A text file is a + * non-binary file who's lines are delimited by the \n character. The file is + * treated as a single message. An optional structured data can be written at + * the end of the file. + * + * No state file are used as it should only grow with time. Instead the state + * is managed using the name of the file. A "glob" allows the module to identify + * "to be treated" files. The module can be configured either to deleted the + * the file on success either to rename the file on success. The size limit is + * fixed by rsyslog max message size global parameter. All files larger than this + * limit produce a message which references it as "too large" and its new location + * The "too large" files are also renamed to keep them available. + * + * This modules allows one to centralize batch reports with other standard logs and + * performance monitoring in a single repository (ElasticSearch, HDFS, ...). This + * centralization helps to identify cause of global performance issues. + * + * Work originally begun on 2014-07-01 by Philippe Duveau @ Pari Mutuel Urbain + * + * This file is contribution of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> /* do NOT remove: will soon be done by the module generation macros */ +#include <sys/types.h> +#include <unistd.h> +#include <glob.h> +#include <fnmatch.h> +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#include "rsyslog.h" /* error codes etc... */ +#include "dirty.h" +#include "cfsysline.h" /* access to config file objects */ +#include "module-template.h" +#include "srUtils.h" /* some utility functions */ +#include "msg.h" +#include "errmsg.h" +#include "glbl.h" +#include "datetime.h" +#include "unicode-helper.h" +#include "prop.h" +#include "stringbuf.h" +#include "ruleset.h" +#include "ratelimit.h" + +#include <regex.h> + +MODULE_TYPE_INPUT /* must be present for input modules, do not remove */ +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imbatchreport") + +/* defines for freebsd */ +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +/* Module static data */ +DEF_IMOD_STATIC_DATA /* must be present, starts static data */ +DEFobjCurrIf(glbl) +DEFobjCurrIf(ruleset) +DEFobjCurrIf(datetime) +DEFobjCurrIf(prop) + +#define SRUCTDATA_BUFFER_LEN 150 +#define READ_BUFFER_LEN 512 +#define FILE_TOO_LARGE "File too large : " +#define FILE_TOO_LARGE_LEN sizeof(FILE_TOO_LARGE)-1 + +#define DFLT_PollInterval 10 + +#define ADD_METADATA_UNSPECIFIED -1 + +typedef enum action_batchreport_t { + action_nothing, + action_rename, + action_delete +} action_batchreport_t; + +struct instanceConf_s { + uchar *pszFollow_glob; + uchar *pszDirName; + uchar *pszFileBaseName; + uchar *pszTag; + int lenTag; + uchar *pszTSk; + int lenTSk; + uchar *pszProgk; + int lenProgk; + int must_stop; + uchar *pszBindRuleset; + int bDedupSpace; + int iFacility; + int iSeverity; + char *ff_regex; + /* Full treatment : this should contain a regex applied on filename. The matching + part is then replaced with ff_replace to put the file out of scan criteria */ + regex_t ff_preg; + + char *ff_rename; + int len_rename; + + char *ff_reject; + int len_reject; + + int filename_oversize; + ruleset_t *pBindRuleset; + /* ruleset to bind listener to (use system default if unspecified) */ + + ratelimit_t *ratelimiter; + + struct instanceConf_s *next; + + action_batchreport_t action; + + char *pszNewFName; + int fd; + + sbool goon; +}; + +/* global configuration variables */ +static struct { + uchar *hostname; + size_t lhostname; + + char *msg_buffer; + size_t max_msg_size; + + instanceConf_t *root; + + /* number of seconds to sleep when there was no file activity */ + int iPollInterval; +} fixedModConf; + +/* config variables */ +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ +}; + +static prop_t *pInputName = NULL; +/* there is only one global inputName for all messages generated by this input */ + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + { "pollinginterval", eCmdHdlrPositiveInt, 0 }, +}; +static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr + }; + +/* input instance parameters */ +static struct cnfparamdescr inppdescr[] = { + { "reports", eCmdHdlrString, CNFPARAM_REQUIRED }, + { "tag", eCmdHdlrString, CNFPARAM_REQUIRED }, + { "programkey", eCmdHdlrString, 0 }, + { "timestampkey", eCmdHdlrString, 0 }, + { "deduplicatespace", eCmdHdlrBinary, 0}, + { "rename", eCmdHdlrString, 0 }, + { "delete", eCmdHdlrString, 0 }, + { "severity", eCmdHdlrSeverity, 0 }, + { "facility", eCmdHdlrFacility, 0 }, + { "ruleset", eCmdHdlrString, 0 }, +}; +static struct cnfparamblk inppblk = + { CNFPARAMBLK_VERSION, + sizeof(inppdescr)/sizeof(struct cnfparamdescr), + inppdescr + }; + +#include "im-helper.h" /* must be included AFTER the type definitions! */ + +/* enqueue the read file line as a message. The provided string is + * not freed - thuis must be done by the caller. + */ +static rsRetVal enqMsg(instanceConf_t *pInst, smsg_t *pMsg) +{ + DEFiRet; + + MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY); + MsgSetInputName(pMsg, pInputName); + MsgSetHOSTNAME(pMsg, fixedModConf.hostname, (const int) fixedModConf.lhostname); + MsgSetTAG(pMsg, pInst->pszTag, pInst->lenTag); + MsgSetPROCID(pMsg, "-"); + MsgSetMSGID(pMsg, "-"); + + pMsg->iFacility = pInst->iFacility >> 3; + pMsg->iSeverity = pInst->iSeverity; + + MsgSetRuleset(pMsg, pInst->pBindRuleset); + + CHKiRet(ratelimitAddMsg(pInst->ratelimiter, NULL, pMsg)); + +finalize_it: + RETiRet; +} + +/* The following is a cancel cleanup handler for strmReadLine(). It is necessary in case + * strmReadLine() is cancelled while processing the stream. -- rgerhards, 2008-03-27 + */ +static void pollFileCancelCleanup(void *pArg) +{ + instanceConf_t *ppInst = (instanceConf_t*) pArg; + if (ppInst->fd > 0) + close(ppInst->fd); + if (ppInst->pszNewFName) + free(ppInst->pszNewFName); +} + +/* readAndSendFile try to read the file and send the message. + * @param pInst point to instance + * @param filename the file name + * @param fstate the file stat + */ +static rsRetVal readAndSendFile(instanceConf_t *pInst, char *filename, char *fpath, struct stat *fstat) +{ + smsg_t *pMsg = NULL; + size_t file_len, read_len = 0, sd_buf_l, msg_len = 0, idx = 0; + int last_is_space = 0; + struct timeval tvm; + uchar sd_buffer[SRUCTDATA_BUFFER_LEN]; + uchar read_buffer[READ_BUFFER_LEN]; + + DEFiRet; + + CHKiRet(msgConstruct(&pMsg)); + + msgAddMetadata(pMsg, (uchar*)"filename", (uchar*)filename); + + /* get the file modification time : end of the batch*/ + tvm.tv_sec = fstat->st_mtime; + tvm.tv_usec = 0; + + file_len = lseek(pInst->fd, 0, SEEK_END); + + MsgSetStructuredData(pMsg, "-"); + + /* Let's read the end of the file first and put it in the buffer for structuredData + * This will help to find the real end of the message + */ + sd_buf_l = (file_len < SRUCTDATA_BUFFER_LEN) ? file_len : SRUCTDATA_BUFFER_LEN; + + if (lseek(pInst->fd, file_len - sd_buf_l, SEEK_SET) >= 0) { + uchar *sdp = sd_buffer+sd_buf_l-1; + int nb_rm = 0; /* number of space chars removed */ + size_t stdata_len = 0, t; + char *tmp; + + if ((t=read(pInst->fd, sd_buffer, sd_buf_l)) != sd_buf_l) { + LogError(0, RS_RET_READ_ERR, "read end of file for structured data failed (%zu / %zu)", + t, sd_buf_l); + return RS_RET_READ_ERR; + } + + /* let's trim the end */ + for (; sdp > sd_buffer && (*sdp=='\n' || *sdp=='\t' || *sdp==' '); sdp--, sd_buf_l--) + file_len--; + + if (sd_buf_l > 1 && *sdp == ']') { + stdata_len = 1; + /* it seems that we have structured data let find the begin */ + for (; sdp > sd_buffer && *sdp!='['; sdp--, stdata_len++) { + if (*sdp == '\n') { + /* line feed not supported in structured data */ + stdata_len--; + memmove(sdp, sdp+1, stdata_len); + nb_rm++; + } + } + if (*sdp == '[') { + /* we got a structured data */ + DBGPRINTF("structured data : %.*s\n", (int)stdata_len, sdp); + MsgAddToStructuredData(pMsg, sdp, stdata_len); + + /* extracting timestamp from structured data overwrite the file creation time */ + if (pInst->pszTSk) { + uchar *field = (uchar*)strstr((char*)sdp, (char*)pInst->pszTSk), v; + if (field != NULL) + { + tvm.tv_sec = 0; + tvm.tv_usec = 0; + for (field += pInst->lenTSk; (v = *field ^ 0x30) <= 9; field++) + tvm.tv_sec = tvm.tv_sec*10 + v; + } + } + + /* extracting program from structured data */ + if (pInst->pszProgk) { + char *field = strstr((char*)sdp, (char*)pInst->pszProgk); + if (field != NULL) + { + tmp = field + pInst->lenProgk; + if ((field = strchr(tmp, '\"')) != NULL) { + *field = '\0'; + MsgSetAPPNAME(pMsg, tmp); + } + } + } + + /* let's trim until useful message end */ + for (sdp--; sdp > sd_buffer && (*sdp=='\n' || *sdp=='\t' || *sdp==' '); sdp--) + nb_rm++; + } + } + /* computing the new file_len */ + file_len -= nb_rm + stdata_len; + } + + datetime.timeval2syslogTime(&tvm, &pMsg->tTIMESTAMP, TIME_IN_UTC); + pMsg->ttGenTime = tvm.tv_sec; + + /* go back to beginning */ + if (lseek(pInst->fd, 0, SEEK_SET) < 0) { + LogError(0, RS_RET_READ_ERR, "readAndSendFile : error while seeking to beginning."); + return RS_RET_READ_ERR; + } + + /* Now read the file */ + msg_len = 0; + while (msg_len < fixedModConf.max_msg_size && (read_len = read(pInst->fd, read_buffer, + (file_len > READ_BUFFER_LEN) ? READ_BUFFER_LEN : file_len)) > 0) { + file_len -= read_len; + idx = 0; + while (read_len > 0 && msg_len < fixedModConf.max_msg_size) { + switch (read_buffer[idx]){ + case '\t': + case ' ': + /* this is to reduce consecutive spaces to only one */ + if (!last_is_space) + fixedModConf.msg_buffer[msg_len++] = ' '; + /* if pInst->bDedupSpace is off last_is_space will never be true */ + last_is_space = pInst->bDedupSpace; + break; + case '\n': + /* this is for trailing spaces */ + if (last_is_space) msg_len--; + fixedModConf.msg_buffer[msg_len++] = '\\'; + /* risk of overflow is managed by making buffer one char longer + * than fixedModConf.max_msg_size */ + fixedModConf.msg_buffer[msg_len++] = 'n'; + break; + default: + fixedModConf.msg_buffer[msg_len++] = read_buffer[idx]; + last_is_space = 0; + } + idx++; + read_len--; + } + } + + close(pInst->fd); + pInst->fd = 0; + + if (file_len > 0 || read_len > 0) { + /* file is too large to be stored in one message */ + memcpy(fixedModConf.msg_buffer, FILE_TOO_LARGE, FILE_TOO_LARGE_LEN); + msg_len = strlen(fpath); + memcpy(fixedModConf.msg_buffer + FILE_TOO_LARGE_LEN, fpath, msg_len); + msg_len += FILE_TOO_LARGE_LEN; + } + + /* file is stored in the message */ + MsgSetRawMsg(pMsg, fixedModConf.msg_buffer, msg_len); + + MsgSetMSGoffs(pMsg, 0); + if ((iRet = enqMsg(pInst, pMsg)) == RS_RET_OK && (file_len > 0 || read_len > 0)) + iRet = RS_RET_FILE_TOO_LARGE; + +finalize_it: + RETiRet; +} + +/* poll a glob */ +static void pollFile(instanceConf_t *pInst) +{ + pInst->fd = 0; + glob_t glob_res; + + pthread_cleanup_push(pollFileCancelCleanup, pInst); + + DBGPRINTF("polling files : %s\n", pInst->pszFollow_glob); + + /* We "glob" to find candidate regular file (or other) */ + if (glob((char*)pInst->pszFollow_glob, GLOB_NOSORT, 0, &glob_res) != 0) + FINALIZE; + + for (size_t i = 0; i < glob_res.gl_pathc && glbl.GetGlobalInputTermState() == 0; i++) + { + struct stat fstat; + rsRetVal ret; + char *filename = strrchr(glob_res.gl_pathv[i], '/'); + if (filename) + filename++; + else + filename = glob_res.gl_pathv[i]; + char *fpath = glob_res.gl_pathv[i]; + + /* let's verify that the file is a regular one */ + if (!stat(fpath, &fstat) && S_ISREG(fstat.st_mode) ) + { + regmatch_t matches[1]; + int toolargeOrFailure = 0; + + DBGPRINTF("Regular file found '%s')\n", fpath); + + /* With this test we verify that we have conditions to remove the + * file from glob scope. If the regular expression not apply we + * can not rename it */ + if (regexec(&pInst->ff_preg, fpath, 1, matches, 0)) { + pInst->must_stop = 1; + FINALIZE; + } + + pInst->fd = open(fpath, + O_NOCTTY | O_RDONLY | O_NONBLOCK | O_LARGEFILE, 0); + + if (pInst->fd <= 0) + { + /* file could be open unfortunately we will try each polling */ + char errStr[512]; + int eno = errno; + rs_strerror_r(eno, errStr, sizeof(errStr)); + LogError(0, RS_RET_READ_ERR,"open the file %s failed with error %s", fpath, errStr); + continue; + } + + /* let's read the file and send it to output */ + ret = readAndSendFile(pInst, filename, fpath, &fstat); + /* is the file to large to be sent */ + toolargeOrFailure = ret == RS_RET_FILE_TOO_LARGE; + + if (ret != RS_RET_OK && ret != RS_RET_FILE_TOO_LARGE) { + LogError(0, ret, "The module could not manage the file %s", fpath); + toolargeOrFailure = 1; + } + + if (pInst->action == action_rename || toolargeOrFailure) + { + pInst->pszNewFName = (char*)malloc(strlen(fpath)+ + pInst->filename_oversize); + memcpy(pInst->pszNewFName, fpath, matches[0].rm_so); + strcpy((char*)pInst->pszNewFName + matches[0].rm_so, + (toolargeOrFailure) ? pInst->ff_reject : pInst->ff_rename); + + if (rename(fpath, pInst->pszNewFName)) + { + /* if the module can not rename the file, it must stop to avoid flooding + * but it keep chance to manage max files as possible + */ + LogError(0, RS_RET_STREAM_DISABLED, "module stopped : was unable" + " to rename form %s to %s.", fpath , pInst->pszNewFName); + pInst->must_stop = 1; + } + else + DBGPRINTF("file %s sent and renamed to %s.\n", fpath, pInst->pszNewFName); + free(pInst->pszNewFName); + pInst->pszNewFName = NULL; + } + else + { + if (unlink(fpath)) + { + /* if the module can not remove the file, it must stop to avoid flooding + * but it keep chance to manage max files as possible + */ + LogError(0, RS_RET_STREAM_DISABLED, "module stopped : unable to delete %s.", + fpath); + pInst->must_stop = 1; + } + else + DBGPRINTF("file %s sent and deleted\n", fpath); + } + } /* if stat */ + } /* for */ + +finalize_it: + globfree(&glob_res); + + pthread_cleanup_pop(0); +} + +static void addInstance(instanceConf_t *inst) { + + if(fixedModConf.root == NULL) { + fixedModConf.root = inst; + } else { + fixedModConf.root->next = inst; + fixedModConf.root = inst; + } +} + +/* create input instance, set default parameters, and + * add it to the list of instances. + */ +static rsRetVal +createInstance(instanceConf_t **pinst) +{ + instanceConf_t *inst; + DEFiRet; + + *pinst = NULL; + + CHKmalloc(inst = (instanceConf_t*)malloc(sizeof(instanceConf_t))); + + inst->next = NULL; + inst->pBindRuleset = NULL; + + inst->pszBindRuleset = NULL; + inst->pszFollow_glob = NULL; + inst->pszDirName = NULL; + inst->pszFileBaseName = NULL; + inst->pszTag = NULL; + inst->pszTSk = NULL; + inst->pszProgk = NULL; + inst->ff_regex = NULL; + inst->ff_rename = NULL; + inst->ff_reject = NULL; + + inst->iSeverity = LOG_NOTICE; + inst->iFacility = LOG_LOCAL0; + inst->len_rename = 0; + inst->len_reject = 0; + inst->bDedupSpace = 1; + inst->goon = 0; + inst->ratelimiter = NULL; + + inst->action = action_nothing; + + inst->must_stop = 0; + + *pinst = inst; +finalize_it: + RETiRet; +} + +/* the basen(ame) buffer must be of size MAXFNAME + * returns the index of the slash in front of basename + */ +static int getBasename(uchar *const __restrict__ basen, uchar *const __restrict__ path) +{ + int i; + const int lenName = ustrlen(path); + for(i = lenName ; i >= 0 ; --i) { + if(path[i] == '/') { + + if(i == lenName) + basen[0] = '\0'; + else { + memcpy(basen, path+i+1, lenName-i); + } + break; + } + } + if (i == -1) { + memcpy(basen, path, lenName); + i = 0; + } + return i; +} + +/* this function checks instance parameters and does some required pre-processing + * (e.g. split filename in path and actual name) + * Note: we do NOT use dirname()/basename() as they have portability problems. + */ +static rsRetVal checkInstance(instanceConf_t *inst) +{ + char dirn[MAXFNAME]; + uchar basen[MAXFNAME]; + int i; + struct stat sb; + int r; + int eno; + char errStr[512], *s, *d; + regmatch_t matches[1]; + DEFiRet; + + i = getBasename(basen, inst->pszFollow_glob); + memcpy(dirn, inst->pszFollow_glob, i); + dirn[i] = '\0'; + CHKmalloc(inst->pszFileBaseName = (uchar*) strdup((char*)basen)); + CHKmalloc(inst->pszDirName = (uchar*) strdup(dirn)); + + if(dirn[0] == '\0') { + dirn[0] = '.'; + dirn[1] = '\0'; + } + r = stat(dirn, &sb); + if(r != 0) { + eno = errno; + rs_strerror_r(eno, errStr, sizeof(errStr)); + LogError(0, RS_RET_CONFIG_ERROR, "Configured directory can not be stated '%s': %s", + dirn, errStr); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + if(!S_ISDIR(sb.st_mode)) { + LogError(0, RS_RET_CONFIG_ERROR, "Configured directory is NOT a directory : '%s'", dirn); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + if (stat((char*)inst->pszFollow_glob, &sb) == 0 && !S_ISREG(sb.st_mode)) { + LogError(0, RS_RET_CONFIG_ERROR, "Configured report is not a glob or a regular file."); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + for (s=(char*)inst->pszFollow_glob, d = dirn; *s; s++, d++) + *d = (*s != '*' && *s != '?') ? *s : '~'; + *d = '\0'; + + if (regexec(&inst->ff_preg, dirn, 1, matches, 0)) { + LogError(0, RS_RET_CONFIG_ERROR, + "Regex does not match globed filenames: Instance ignored to avoid loops."); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + if (inst->action == action_rename) { + strcpy(dirn + matches[0].rm_so, inst->ff_rename); + if (fnmatch((char*)inst->pszFollow_glob, dirn, FNM_PATHNAME) == 0) + { + LogError(0, RS_RET_INVALID_PARAMS, + "Normal renaming leaves files in glob scope: Instance ignored to avoid loops."); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + } + strcpy(dirn + matches[0].rm_so, inst->ff_reject); + if (fnmatch((char*)inst->pszFollow_glob, dirn, FNM_PATHNAME) == 0) + { + LogError(0, RS_RET_INVALID_PARAMS, + "Reject renaming leaves files in glob scope: Instance ignored to avoid loops."); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + dbgprintf("instance checked"); + +finalize_it: + RETiRet; +} + +static void freeInstance(instanceConf_t *inst) { + if (inst == NULL) + return; + + if (inst->pszBindRuleset) free(inst->pszBindRuleset); + if (inst->pszFollow_glob) free(inst->pszFollow_glob); + if (inst->pszDirName) free(inst->pszDirName); + if (inst->pszFileBaseName) free(inst->pszFileBaseName); + if (inst->pszTag) free(inst->pszTag); + if (inst->pszTSk) free(inst->pszTSk); + if (inst->pszProgk) free(inst->pszProgk); + + if (inst->len_reject) regfree(&inst->ff_preg); + + if (inst->ff_regex) free(inst->ff_regex); + if (inst->ff_rename) free(inst->ff_rename); + if (inst->ff_reject) free(inst->ff_reject); + + if (inst->ratelimiter) ratelimitDestruct(inst->ratelimiter); + free(inst); +} + +BEGINnewInpInst + struct cnfparamvals *pvals; + instanceConf_t *inst = NULL; + int i; + char *temp; +CODESTARTnewInpInst + DBGPRINTF("newInpInst (imbatchreport)\n"); + + pvals = nvlstGetParams(lst, &inppblk, NULL); + if(pvals == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + DBGPRINTF("input param blk in imbatchreport:\n"); + if(Debug) cnfparamsPrint(&inppblk, pvals); + + CHKiRet(createInstance(&inst)); + + for(i = 0 ; i < inppblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(inppblk.descr[i].name, "reports")) { + inst->pszFollow_glob = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "tag")) { + inst->pszTag = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + inst->lenTag = ustrlen(inst->pszTag); + } else if(!strcmp(inppblk.descr[i].name, "programkey")) { + inst->pszProgk = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + inst->lenProgk = ustrlen(inst->pszProgk) + 2; + } else if(!strcmp(inppblk.descr[i].name, "timestampkey")) { + inst->pszTSk = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + inst->lenTSk = ustrlen(inst->pszTSk) + 1; + } else if(!strcmp(inppblk.descr[i].name, "deduplicatespace")) { + inst->bDedupSpace = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "ruleset")) { + inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "severity")) { + inst->iSeverity = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "facility")) { + inst->iFacility = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "rename")) { + if (inst->action == action_delete) + { + LogError(0, RS_RET_PARAM_ERROR, "'rename' and 'delete' are exclusive !"); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + + inst->ff_regex = es_str2cstr(pvals[i].val.d.estr, NULL); + + while ((temp = strchr(inst->ff_regex, '\t')) != NULL) + *temp = ' '; + + inst->len_reject = 0; + + if ((inst->ff_rename = strchr(inst->ff_regex, ' ')) != NULL ) { + *inst->ff_rename++ = '\0'; + + while (*inst->ff_rename == ' ') inst->ff_rename++; + if ((inst->ff_reject = strchr(inst->ff_rename, ' ')) != NULL ) { + + *inst->ff_reject++ = '\0'; + while (*inst->ff_reject == ' ') inst->ff_reject++; + + temp = strchr(inst->ff_reject, ' '); + if (temp) *temp = '\0'; + + if (strcmp(inst->ff_rename, "-")){ + inst->ff_rename = strdup(inst->ff_rename); + inst->len_rename = strlen(inst->ff_rename); + }else{ + inst->ff_rename = strdup(""); + inst->len_rename = 0; + } + + inst->ff_reject = strdup(inst->ff_reject); + inst->len_reject = strlen(inst->ff_reject); + + if (inst->len_reject && regcomp(&inst->ff_preg, + (char*)inst->ff_regex, + REG_EXTENDED)) + { + inst->len_reject = 0; + LogError(0, RS_RET_SYNTAX_ERROR, "The first part of 'rename' " + "parameter does not contain a valid regex"); + ABORT_FINALIZE(RS_RET_SYNTAX_ERROR); + } + } + } + if (inst->len_reject == 0) + { + LogError(0, RS_RET_PARAM_ERROR, "'rename' must specify THREE " + "parameters separated by spaces or tabs ! The second " + "parameter can be a null string to get this use a '-'."); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + + inst->action = action_rename; + + } else if(!strcmp(inppblk.descr[i].name, "delete")) { + if (inst->action == action_rename) + { + LogError(0, RS_RET_PARAM_ERROR, "'rename' and 'delete' are exclusive !"); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + + inst->ff_regex = es_str2cstr(pvals[i].val.d.estr, NULL); + + while ((temp = strchr(inst->ff_regex, '\t')) != NULL) + *temp = ' '; + + inst->len_reject = 0; + + if ((inst->ff_reject = strchr(inst->ff_regex, ' ')) != NULL ) { + *inst->ff_reject++ = '\0'; + + while (*inst->ff_reject == ' ') inst->ff_reject++; + + temp = strchr(inst->ff_reject, ' '); + if (temp) *temp = '\0'; + + inst->ff_reject = strdup(inst->ff_reject); + inst->len_reject = strlen(inst->ff_reject); + + if (regcomp(&inst->ff_preg, (char*)inst->ff_regex, REG_EXTENDED)) + { + inst->len_reject = 0; + LogError(0, RS_RET_SYNTAX_ERROR, + "The first part of 'delete' parameter does not contain a valid regex"); + ABORT_FINALIZE(RS_RET_SYNTAX_ERROR); + } + + } + + if (inst->len_reject == 0) + { + LogError(0, RS_RET_PARAM_ERROR, + "'delete' must specify TWO parameters separated by spaces or tabs !"); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + inst->action = action_delete; + + } else { + dbgprintf("Configuration param '%s' non-handled\n", inppblk.descr[i].name); + } + } + + if(inst->action == action_nothing) { + LogError(0, RS_RET_PARAM_NOT_PERMITTED, "either 'rename' or 'delete' must be set"); + ABORT_FINALIZE(RS_RET_PARAM_NOT_PERMITTED); + } + + inst->filename_oversize = (inst->len_rename > inst->len_reject) ? inst->len_rename : inst->len_reject; + + CHKiRet(ratelimitNew(&inst->ratelimiter, "imbatchreport", (char*)inst->pszFollow_glob)); + + inst->goon = 1; + + CHKiRet(checkInstance(inst)); + +finalize_it: +CODE_STD_FINALIZERnewInpInst + + if (iRet == RS_RET_OK) + addInstance(inst); + else + freeInstance(inst); + + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + pModConf->pConf = pConf; + fixedModConf.iPollInterval = DFLT_PollInterval; + + fixedModConf.msg_buffer = NULL; + fixedModConf.root = NULL; +ENDbeginCnfLoad + + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for imbatchreport:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(modpblk.descr[i].name, "pollinginterval")) { + fixedModConf.iPollInterval = (int) pvals[i].val.d.n; + } else { + dbgprintf("program error, non-handled " + "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); + } + } +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + + +BEGINendCnfLoad +CODESTARTendCnfLoad + dbgprintf("polling interval is %d\n", + fixedModConf.iPollInterval); +ENDendCnfLoad + + +BEGINcheckCnf + instanceConf_t *inst; +CODESTARTcheckCnf + for(inst = fixedModConf.root ; inst != NULL ; inst = inst->next) { + std_checkRuleset(pModConf, inst); + } + if(fixedModConf.root == NULL) { + LogError(0, RS_RET_NO_LISTNERS, + "no files configured to be monitored - no input will be gathered"); + iRet = RS_RET_NO_LISTNERS; + } +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + +BEGINfreeCnf + instanceConf_t *inst, *del; +CODESTARTfreeCnf + for(inst = fixedModConf.root ; inst != NULL ; ) { + del = inst; + inst = inst->next; + freeInstance(del); + } +ENDfreeCnf + +BEGINwillRun +CODESTARTwillRun + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imbatchreport"), + sizeof("imbatchreport") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); + + fixedModConf.max_msg_size = glbl.GetMaxLine(runConf); + DBGPRINTF("Max message len %zu\n", fixedModConf.max_msg_size); + CHKmalloc(fixedModConf.msg_buffer = (char*)malloc(fixedModConf.max_msg_size + 1)); +finalize_it: +ENDwillRun + +BEGINrunInput +CODESTARTrunInput + fixedModConf.hostname = glbl.GetLocalHostName(); + fixedModConf.lhostname = ustrlen(fixedModConf.hostname); + + while(glbl.GetGlobalInputTermState() == 0) { + instanceConf_t *pInst; + for(pInst = fixedModConf.root ; pInst != NULL ; pInst = pInst->next) { + if (pInst->goon) { + if(glbl.GetGlobalInputTermState() == 1) + break; + pollFile(pInst); + /* We got a major problem so */ + pInst->goon = !pInst->must_stop; + } + } + + if(glbl.GetGlobalInputTermState() == 0) + srSleep(fixedModConf.iPollInterval, 10); + } + DBGPRINTF("terminating upon request of rsyslog core\n"); + RETiRet; +ENDrunInput + +/* This function is called by the framework after runInput() has been terminated. It + * shall free any resources and prepare the module for unload. + */ +BEGINafterRun +CODESTARTafterRun + if (fixedModConf.msg_buffer) + free(fixedModConf.msg_buffer); + if(pInputName != NULL) + prop.Destruct(&pInputName); +ENDafterRun + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURENonCancelInputTermination) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +/* The following entry points are defined in module-template.h. + * In general, they need to be present, but you do NOT need to provide + * any code here. + */ +BEGINmodExit +CODESTARTmodExit + + objRelease(datetime, CORE_COMPONENT); + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); + +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + +/* modInit() is called once the module is loaded. It must perform all module-wide + * initialization tasks. There are also a number of housekeeping tasks that the + * framework requires. These are handled by the macros. Please note that the + * complexity of processing is depending on the actual module. However, only + * thing absolutely necessary should be done here. Actual app-level processing + * is to be performed in runInput(). A good sample of what to do here may be to + * set some variable defaults. + */ +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); +ENDmodInit + + +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, + instanceConf_t *inst) +{ + LogError(0, NO_ERRCODE, "ruleset '%s' for %s not found - " + "using default ruleset instead", inst->pszBindRuleset, + inst->pszFollow_glob); +} diff --git a/contrib/imczmq/Makefile.am b/contrib/imczmq/Makefile.am new file mode 100644 index 0000000..9bf7adb --- /dev/null +++ b/contrib/imczmq/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = imczmq.la + +imczmq_la_SOURCES = imczmq.c +imczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) +imczmq_la_LDFLAGS = -module -avoid-version +imczmq_la_LIBADD = $(CZMQ_LIBS) + +EXTRA_DIST = diff --git a/contrib/imczmq/Makefile.in b/contrib/imczmq/Makefile.in new file mode 100644 index 0000000..9782e4b --- /dev/null +++ b/contrib/imczmq/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/imczmq +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +imczmq_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_imczmq_la_OBJECTS = imczmq_la-imczmq.lo +imczmq_la_OBJECTS = $(am_imczmq_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +imczmq_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(imczmq_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imczmq_la-imczmq.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imczmq_la_SOURCES) +DIST_SOURCES = $(imczmq_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = imczmq.la +imczmq_la_SOURCES = imczmq.c +imczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) +imczmq_la_LDFLAGS = -module -avoid-version +imczmq_la_LIBADD = $(CZMQ_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imczmq/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/imczmq/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +imczmq.la: $(imczmq_la_OBJECTS) $(imczmq_la_DEPENDENCIES) $(EXTRA_imczmq_la_DEPENDENCIES) + $(AM_V_CCLD)$(imczmq_la_LINK) -rpath $(pkglibdir) $(imczmq_la_OBJECTS) $(imczmq_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imczmq_la-imczmq.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +imczmq_la-imczmq.lo: imczmq.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imczmq_la-imczmq.lo -MD -MP -MF $(DEPDIR)/imczmq_la-imczmq.Tpo -c -o imczmq_la-imczmq.lo `test -f 'imczmq.c' || echo '$(srcdir)/'`imczmq.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imczmq_la-imczmq.Tpo $(DEPDIR)/imczmq_la-imczmq.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imczmq.c' object='imczmq_la-imczmq.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imczmq_la-imczmq.lo `test -f 'imczmq.c' || echo '$(srcdir)/'`imczmq.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/imczmq_la-imczmq.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/imczmq_la-imczmq.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/imczmq/README b/contrib/imczmq/README new file mode 100644 index 0000000..369a82a --- /dev/null +++ b/contrib/imczmq/README @@ -0,0 +1,39 @@ +CZMQ Input Plugin + +REQUIREMENTS: + +* libsodium ( https://github.com/jedisct1/libsodium ) +* zeromq v4.x build with libsodium support ( http://zeromq.org/ ) +* czmq 3.x ( http://czmq.zeromq.org/ ) + +------------------------------------------------------------------------------- +module( + load="imczmq" + servercertpath="/etc/curve.d/server" + clientcertpath="/etc/curve.d/" + authtype="CURVESERVER" + authenticator="on" +) + +input( + type="imczmq" + endpoints="@tcp://*:24555" + socktype="PULL" +) +------------------------------------------------------------------------------- + +Explanation of Options: + +Module +------ +servercertpath: path to server cert if using CURVE +clientcertpath: path to client cert(s) if using CURVE +authtype: CURVESERVER, CURVECLIENT (omit for no auth) +authenticator: whether to start an authenticator thread + +Action +------ +type: type of action (imczmq for this plugin) +endpoints: comma delimited list of zeromq endpoints (see zeromq documentation) +socktype: zeromq socket type (currently supports PULL, SUB, ROUTER, DISH, SERVER) +authtype: CURVECLIENT or CURVESERVER diff --git a/contrib/imczmq/imczmq.c b/contrib/imczmq/imczmq.c new file mode 100644 index 0000000..77674d4 --- /dev/null +++ b/contrib/imczmq/imczmq.c @@ -0,0 +1,632 @@ +/* imczmq.c + * Copyright (C) 2016 Brian Knox + * Copyright (C) 2014 Rainer Gerhards + * + * Author: Brian Knox <bknox@digitalocean.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "rsyslog.h" +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "cfsysline.h" +#include "dirty.h" +#include "errmsg.h" +#include "glbl.h" +#include "module-template.h" +#include "msg.h" +#include "net.h" +#include "parser.h" +#include "prop.h" +#include "ruleset.h" +#include "srUtils.h" +#include "unicode-helper.h" +#include <czmq.h> + +MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imczmq"); + +DEF_IMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) + +static struct cnfparamdescr modpdescr[] = { + { "authenticator", eCmdHdlrBinary, 0 }, + { "authtype", eCmdHdlrString, 0 }, + { "servercertpath", eCmdHdlrString, 0 }, + { "clientcertpath", eCmdHdlrString, 0 }, +}; + +static struct cnfparamblk modpblk = { + CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr +}; + +struct modConfData_s { + rsconf_t *pConf; + instanceConf_t *root; + instanceConf_t *tail; + int authenticator; + char *authType; + char *serverCertPath; + char *clientCertPath; +}; + +struct instanceConf_s { + bool serverish; + int sockType; + char *sockEndpoints; + char *topics; + uchar *pszBindRuleset; + ruleset_t *pBindRuleset; + struct instanceConf_s *next; +}; + +struct listener_t { + zsock_t *sock; + ruleset_t *ruleset; +}; + +static zlist_t *listenerList; +static modConfData_t *runModConf = NULL; +static prop_t *s_namep = NULL; + +static struct cnfparamdescr inppdescr[] = { + { "endpoints", eCmdHdlrGetWord, 1 }, + { "socktype", eCmdHdlrGetWord, 1 }, + { "ruleset", eCmdHdlrGetWord, 0 }, + { "topics", eCmdHdlrGetWord, 0 }, +}; + +#include "im-helper.h" + +static struct cnfparamblk inppblk = { + CNFPARAMBLK_VERSION, + sizeof(inppdescr) / sizeof(struct cnfparamdescr), + inppdescr +}; + +static void setDefaults(instanceConf_t* iconf) { + iconf->serverish = true; + iconf->sockType = -1; + iconf->sockEndpoints = NULL; + iconf->topics = NULL; + iconf->pszBindRuleset = NULL; + iconf->pBindRuleset = NULL; + iconf->next = NULL; +}; + +static rsRetVal createInstance(instanceConf_t** pinst) { + DEFiRet; + instanceConf_t* inst; + CHKmalloc(inst = malloc(sizeof(instanceConf_t))); + + setDefaults(inst); + + if(runModConf->root == NULL || runModConf->tail == NULL) { + runModConf->tail = runModConf->root = inst; + } + else { + runModConf->tail->next = inst; + runModConf->tail = inst; + } + *pinst = inst; +finalize_it: + RETiRet; +} + +static rsRetVal addListener(instanceConf_t* iconf){ + DEFiRet; + + DBGPRINTF("imczmq: addListener called..\n"); + struct listener_t* pData = NULL; + CHKmalloc(pData=(struct listener_t*)malloc(sizeof(struct listener_t))); + pData->ruleset = iconf->pBindRuleset; + + pData->sock = zsock_new(iconf->sockType); + if(!pData->sock) { + LogError(0, RS_RET_NO_ERRCODE, + "imczmq: new socket failed for endpoints: %s", + iconf->sockEndpoints); + ABORT_FINALIZE(RS_RET_NO_ERRCODE); + } + + DBGPRINTF("imczmq: created socket of type %d..\n", iconf->sockType); + + if(runModConf->authType) { + if(!strcmp(runModConf->authType, "CURVESERVER")) { + DBGPRINTF("imczmq: we are a CURVESERVER\n"); + zcert_t *serverCert = zcert_load(runModConf->serverCertPath); + if(!serverCert) { + LogError(0, NO_ERRCODE, "could not load cert %s", + runModConf->serverCertPath); + ABORT_FINALIZE(RS_RET_ERR); + } + zsock_set_zap_domain(pData->sock, "global"); + zsock_set_curve_server(pData->sock, 1); + zcert_apply(serverCert, pData->sock); + zcert_destroy(&serverCert); + } + else if(!strcmp(runModConf->authType, "CURVECLIENT")) { + DBGPRINTF("imczmq: we are a CURVECLIENT\n"); + zcert_t *serverCert = zcert_load(runModConf->serverCertPath); + if(!serverCert) { + LogError(0, NO_ERRCODE, "could not load cert %s", + runModConf->serverCertPath); + ABORT_FINALIZE(RS_RET_ERR); + } + const char *server_key = zcert_public_txt(serverCert); + zcert_destroy(&serverCert); + zsock_set_curve_serverkey(pData->sock, server_key); + + zcert_t *clientCert = zcert_load(runModConf->clientCertPath); + if(!clientCert) { + LogError(0, NO_ERRCODE, "could not load cert %s", + runModConf->clientCertPath); + ABORT_FINALIZE(RS_RET_ERR); + } + + zcert_apply(clientCert, pData->sock); + zcert_destroy(&clientCert); + } + + } + + switch(iconf->sockType) { + case ZMQ_SUB: +#if defined(ZMQ_DISH) + case ZMQ_DISH: +#endif + iconf->serverish = false; + break; + case ZMQ_PULL: +#if defined(ZMQ_GATHER) + case ZMQ_GATHER: +#endif + case ZMQ_ROUTER: +#if defined(ZMQ_SERVER) + case ZMQ_SERVER: +#endif + iconf->serverish = true; + break; + } + + if(iconf->topics) { + // A zero-length topic means subscribe to everything + if(!*iconf->topics && iconf->sockType == ZMQ_SUB) { + DBGPRINTF("imczmq: subscribing to all topics\n"); + zsock_set_subscribe(pData->sock, ""); + } + + char topic[256]; + while(*iconf->topics) { + char *delimiter = strchr(iconf->topics, ','); + if(!delimiter) { + delimiter = iconf->topics + strlen(iconf->topics); + } + memcpy (topic, iconf->topics, delimiter - iconf->topics); + topic[delimiter-iconf->topics] = 0; + DBGPRINTF("imczmq: subscribing to %s\n", topic); + if(iconf->sockType == ZMQ_SUB) { + zsock_set_subscribe (pData->sock, topic); + } +#if defined(ZMQ_DISH) + else if(iconf->sockType == ZMQ_DISH) { + int rc = zsock_join (pData->sock, topic); + if(rc != 0) { + LogError(0, NO_ERRCODE, "could not join group %s", topic); + ABORT_FINALIZE(RS_RET_ERR); + } + } +#endif + if(*delimiter == 0) { + break; + } + iconf->topics = delimiter + 1; + } + } + + int rc = zsock_attach(pData->sock, (const char*)iconf->sockEndpoints, + iconf->serverish); + if (rc == -1) { + LogError(0, NO_ERRCODE, "zsock_attach to %s failed", + iconf->sockEndpoints); + ABORT_FINALIZE(RS_RET_ERR); + } + + DBGPRINTF("imczmq: attached socket to %s\n", iconf->sockEndpoints); + + rc = zlist_append(listenerList, (void *)pData); + if(rc != 0) { + LogError(0, NO_ERRCODE, "could not append listener"); + ABORT_FINALIZE(RS_RET_ERR); + } +finalize_it: + if(iRet != RS_RET_OK) { + free(pData); + } + RETiRet; +} + +static rsRetVal rcvData(void){ + DEFiRet; + + if(!listenerList) { + listenerList = zlist_new(); + if(!listenerList) { + LogError(0, NO_ERRCODE, "could not allocate list"); + ABORT_FINALIZE(RS_RET_ERR); + } + } + + zactor_t *authActor = NULL; + + if(runModConf->authenticator == 1) { + authActor = zactor_new(zauth, NULL); + zstr_sendx(authActor, "CURVE", runModConf->clientCertPath, NULL); + zsock_wait(authActor); + } + + instanceConf_t *inst; + for(inst = runModConf->root; inst != NULL; inst=inst->next) { + CHKiRet(addListener(inst)); + } + + zpoller_t *poller = zpoller_new(NULL); + if(!poller) { + LogError(0, NO_ERRCODE, "could not create poller"); + ABORT_FINALIZE(RS_RET_ERR); + } + DBGPRINTF("imczmq: created poller\n"); + + struct listener_t *pData; + + pData = zlist_first(listenerList); + if(!pData) { + LogError(0, NO_ERRCODE, "imczmq: no listeners were " + "started, input not activated.\n"); + ABORT_FINALIZE(RS_RET_NO_RUN); + } + + while(pData) { + int rc = zpoller_add(poller, pData->sock); + if(rc != 0) { + LogError(0, NO_ERRCODE, "imczmq: could not add " + "socket to poller, input not activated.\n"); + ABORT_FINALIZE(RS_RET_NO_RUN); + } + pData = zlist_next(listenerList); + } + + zsock_t *which = (zsock_t *)zpoller_wait(poller, -1); + while(which) { + if (zpoller_terminated(poller)) { + break; + } + pData = zlist_first(listenerList); + while(pData->sock != which) { + pData = zlist_next(listenerList); + } + + if(which == pData->sock) { + DBGPRINTF("imczmq: found matching socket\n"); + } + + zframe_t *frame = zframe_recv(which); + char *buf = NULL; + + if (frame != NULL) + buf = zframe_strdup(frame); + + zframe_destroy(&frame); + + if(buf == NULL) { + DBGPRINTF("imczmq: null buffer\n"); + continue; + } + smsg_t *pMsg; + if(msgConstruct(&pMsg) == RS_RET_OK) { + MsgSetRawMsg(pMsg, buf, strlen(buf)); + MsgSetInputName(pMsg, s_namep); + MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); + MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); + MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); + MsgSetMSGoffs(pMsg, 0); + MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); + MsgSetRuleset(pMsg, pData->ruleset); + pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; + submitMsg2(pMsg); + } + + free(buf); + which = (zsock_t *)zpoller_wait(poller, -1); + } +finalize_it: + zpoller_destroy(&poller); + pData = zlist_first(listenerList); + while(pData) { + zsock_destroy(&pData->sock); + free(pData->ruleset); + pData = zlist_next(listenerList); + } + zlist_destroy(&listenerList); + zactor_destroy(&authActor); + RETiRet; +} + +BEGINrunInput +CODESTARTrunInput + iRet = rcvData(); +ENDrunInput + + +BEGINwillRun +CODESTARTwillRun + CHKiRet(prop.Construct(&s_namep)); + CHKiRet(prop.SetString(s_namep, + UCHAR_CONSTANT("imczmq"), + sizeof("imczmq") - 1)); + + CHKiRet(prop.ConstructFinalize(s_namep)); + +finalize_it: +ENDwillRun + + +BEGINafterRun +CODESTARTafterRun + if(s_namep != NULL) { + prop.Destruct(&s_namep); + } +ENDafterRun + + +BEGINmodExit +CODESTARTmodExit + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); +ENDmodExit + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURENonCancelInputTermination) { + iRet = RS_RET_OK; + } +ENDisCompatibleWithFeature + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + runModConf = pModConf; + runModConf->pConf = pConf; + runModConf->authenticator = 0; + runModConf->authType = NULL; + runModConf->serverCertPath = NULL; + runModConf->clientCertPath = NULL; +ENDbeginCnfLoad + + +BEGINsetModCnf + struct cnfparamvals* pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(NULL == pvals) { + LogError(0, RS_RET_MISSING_CNFPARAMS, + "imczmq: error processing module " + "config parameters ['module(...)']"); + + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + for(i=0; i < modpblk.nParams; ++i) { + if(!pvals[i].bUsed) { + continue; + } + if(!strcmp(modpblk.descr[i].name, "authenticator")) { + runModConf->authenticator = (int)pvals[i].val.d.n; + } + else if(!strcmp(modpblk.descr[i].name, "authtype")) { + runModConf->authType = es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if(!strcmp(modpblk.descr[i].name, "servercertpath")) { + runModConf->serverCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if(!strcmp(modpblk.descr[i].name, "clientcertpath")) { + runModConf->clientCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); + } + else { + LogError(0, RS_RET_INVALID_PARAMS, + "imczmq: config error, unknown " + "param %s in setModCnf\n", + modpblk.descr[i].name); + } + } + + DBGPRINTF("imczmq: authenticator set to %d\n", runModConf->authenticator); + DBGPRINTF("imczmq: authType set to %s\n", runModConf->authType); + DBGPRINTF("imczmq: serverCertPath set to %s\n", runModConf->serverCertPath); + DBGPRINTF("imczmq: clientCertPath set to %s\n", runModConf->clientCertPath); + +finalize_it: + if(pvals != NULL) { + cnfparamvalsDestruct(pvals, &modpblk); + } +ENDsetModCnf + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) +{ + LogError(0, NO_ERRCODE, + "imczmq: ruleset '%s' for socket %s not found - " + "using default ruleset instead", inst->pszBindRuleset, + inst->sockEndpoints); +} + + +BEGINcheckCnf +instanceConf_t* inst; +CODESTARTcheckCnf + for(inst = pModConf->root; inst!=NULL; inst=inst->next) { + std_checkRuleset(pModConf, inst); + } +ENDcheckCnf + + +BEGINactivateCnfPrePrivDrop +CODESTARTactivateCnfPrePrivDrop + runModConf = pModConf; + putenv((char*)"ZSYS_SIGHANDLER=false"); +ENDactivateCnfPrePrivDrop + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf + instanceConf_t *inst, *inst_r; +CODESTARTfreeCnf + free(pModConf->authType); + free(pModConf->serverCertPath); + free(pModConf->clientCertPath); + for (inst = pModConf->root ; inst != NULL ; ) { + free(inst->pszBindRuleset); + free(inst->sockEndpoints); + inst_r = inst; + inst = inst->next; + free(inst_r); + } + +ENDfreeCnf + + +BEGINnewInpInst + struct cnfparamvals* pvals; + instanceConf_t* inst; + int i; +CODESTARTnewInpInst + DBGPRINTF("newInpInst (imczmq)\n"); + + pvals = nvlstGetParams(lst, &inppblk, NULL); + if(NULL==pvals) { + LogError(0, RS_RET_MISSING_CNFPARAMS, + "imczmq: required parameters are missing\n"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + DBGPRINTF("imczmq: input param blk:\n"); + cnfparamsPrint(&inppblk, pvals); + } + + CHKiRet(createInstance(&inst)); + + for(i = 0 ; i < inppblk.nParams ; ++i) { + if(!pvals[i].bUsed) { + continue; + } + + if(!strcmp(inppblk.descr[i].name, "ruleset")) { + inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if(!strcmp(inppblk.descr[i].name, "endpoints")) { + inst->sockEndpoints = es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if(!strcmp(inppblk.descr[i].name, "topics")) { + inst->topics = es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if(!strcmp(inppblk.descr[i].name, "socktype")){ + char *stringType = es_str2cstr(pvals[i].val.d.estr, NULL); + if( NULL == stringType ){ + LogError(0, RS_RET_CONFIG_ERROR, + "imczmq: out of memory error copying sockType param"); + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + + if(!strcmp("PULL", stringType)) { + inst->sockType = ZMQ_PULL; + } +#if defined(ZMQ_GATHER) + else if(!strcmp("GATHER", stringType)) { + inst->sockType = ZMQ_GATHER; + } +#endif + else if(!strcmp("SUB", stringType)) { + inst->sockType = ZMQ_SUB; + } +#if defined(ZMQ_DISH) + else if(!strcmp("DISH", stringType)) { + inst->sockType = ZMQ_DISH; + } +#endif + else if(!strcmp("ROUTER", stringType)) { + inst->sockType = ZMQ_ROUTER; + } +#if defined(ZMQ_SERVER) + else if(!strcmp("SERVER", stringType)) { + inst->sockType = ZMQ_SERVER; + } +#endif + free(stringType); + + } + else { + LogError(0, NO_ERRCODE, + "imczmq: program error, non-handled " + "param '%s'\n", inppblk.descr[i].name); + } + } +finalize_it: +CODE_STD_FINALIZERnewInpInst + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES +CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); +ENDmodInit + diff --git a/contrib/imdocker/Makefile.am b/contrib/imdocker/Makefile.am new file mode 100644 index 0000000..68c516e --- /dev/null +++ b/contrib/imdocker/Makefile.am @@ -0,0 +1,6 @@ +pkglib_LTLIBRARIES = imdocker.la + +imdocker_la_SOURCES = imdocker.c +imdocker_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(CURL_CFLAGS) $(LIBLOGGING_STDLOG_CFLAGS) +imdocker_la_LDFLAGS = -module -avoid-version +imdocker_la_LIBADD = $(CURL_LIBS) diff --git a/contrib/imdocker/Makefile.in b/contrib/imdocker/Makefile.in new file mode 100644 index 0000000..2421da3 --- /dev/null +++ b/contrib/imdocker/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/imdocker +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +imdocker_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_imdocker_la_OBJECTS = imdocker_la-imdocker.lo +imdocker_la_OBJECTS = $(am_imdocker_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +imdocker_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(imdocker_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imdocker_la-imdocker.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imdocker_la_SOURCES) +DIST_SOURCES = $(imdocker_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = imdocker.la +imdocker_la_SOURCES = imdocker.c +imdocker_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(CURL_CFLAGS) $(LIBLOGGING_STDLOG_CFLAGS) +imdocker_la_LDFLAGS = -module -avoid-version +imdocker_la_LIBADD = $(CURL_LIBS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imdocker/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/imdocker/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +imdocker.la: $(imdocker_la_OBJECTS) $(imdocker_la_DEPENDENCIES) $(EXTRA_imdocker_la_DEPENDENCIES) + $(AM_V_CCLD)$(imdocker_la_LINK) -rpath $(pkglibdir) $(imdocker_la_OBJECTS) $(imdocker_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imdocker_la-imdocker.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +imdocker_la-imdocker.lo: imdocker.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imdocker_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imdocker_la-imdocker.lo -MD -MP -MF $(DEPDIR)/imdocker_la-imdocker.Tpo -c -o imdocker_la-imdocker.lo `test -f 'imdocker.c' || echo '$(srcdir)/'`imdocker.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imdocker_la-imdocker.Tpo $(DEPDIR)/imdocker_la-imdocker.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imdocker.c' object='imdocker_la-imdocker.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imdocker_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imdocker_la-imdocker.lo `test -f 'imdocker.c' || echo '$(srcdir)/'`imdocker.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/imdocker_la-imdocker.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/imdocker_la-imdocker.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/imdocker/imdocker.c b/contrib/imdocker/imdocker.c new file mode 100644 index 0000000..d7445ea --- /dev/null +++ b/contrib/imdocker/imdocker.c @@ -0,0 +1,1794 @@ +/* imdocker.c + * This is an implementation of the docker container log input module. It uses the + * Docker API in order to stream all container logs available on a host. Will also + * update relevant container metadata. + * + * Copyright (C) 2018, 2019 the rsyslog project. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef __sun +#define _XPG4_2 +#endif +#include "config.h" +#include "rsyslog.h" +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <errno.h> +#include <curl/curl.h> +#include <json.h> +#include <assert.h> +#include <signal.h> +#include <stdbool.h> +#include "cfsysline.h" /* access to config file objects */ +#include "unicode-helper.h" +#include "module-template.h" +#include "srUtils.h" /* some utility functions */ +#include "errmsg.h" +#include "net.h" +#include "glbl.h" +#include "msg.h" +#include "parser.h" +#include "prop.h" +#include "debug.h" +#include "statsobj.h" +#include "datetime.h" +#include "ratelimit.h" +#include "hashtable.h" +#include "hashtable_itr.h" + +#if !defined(_AIX) +#pragma GCC diagnostic ignored "-Wswitch-enum" +#endif + +MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imdocker") + +extern int Debug; + +#define USE_MULTI_LINE +#undef ENABLE_DEBUG_BYTE_BUFFER + +/* defines */ +#define DOCKER_TAG_NAME "docker:" + +#define DOCKER_CONTAINER_ID_PARSE_NAME "Id" +#define DOCKER_CONTAINER_NAMES_PARSE_NAME "Names" +#define DOCKER_CONTAINER_IMAGEID_PARSE_NAME "ImageID" +#define DOCKER_CONTAINER_CREATED_PARSE_NAME "Created" +#define DOCKER_CONTAINER_LABELS_PARSE_NAME "Labels" + +/* label defines */ +#define DOCKER_CONTAINER_LABEL_KEY_STARTREGEX "imdocker.startregex" + +/* DEFAULT VALUES */ +#define DFLT_pollingInterval 60 /* polling interval in seconds */ +#define DFLT_retrieveNewLogsFromStart 1/* Process newly found containers logs from start */ +#define DFLT_containersLimit 25 /* maximum number of containers */ +#define DFLT_trimLineOverBytes 4194304 /* limit log lines to the value - 4MB default */ +#define DFLT_bEscapeLF 1 /* whether line feeds should be escaped */ + +#define DFLT_SEVERITY pri2sev(LOG_INFO) +#define DFLT_FACILITY pri2fac(LOG_USER) + +enum { + dst_invalid = -1, + dst_stdin, + dst_stdout, + dst_stderr, + dst_stream_type_count +} docker_stream_type_t; + +/* imdocker specific structs */ +typedef struct imdocker_buf_s { + uchar *data; + size_t len; + size_t data_size; +} imdocker_buf_t; + +typedef struct docker_cont_logs_buf_s { + imdocker_buf_t *buf; + int8_t stream_type; + size_t bytes_remaining; +} docker_cont_logs_buf_t; + +struct docker_cont_logs_inst_s; +typedef rsRetVal (*submitmsg_funcptr) (struct docker_cont_logs_inst_s *pInst, docker_cont_logs_buf_t *pBufdata, + const uchar* pszTag); +typedef submitmsg_funcptr SubmitMsgFuncPtr; + +/* curl request instance */ +typedef struct docker_cont_logs_req_s { + CURL *curl; + docker_cont_logs_buf_t* data_bufs[dst_stream_type_count]; + SubmitMsgFuncPtr submitMsg; +} docker_cont_logs_req_t; + +typedef struct imdocker_req_s { + CURL *curl; + imdocker_buf_t *buf; +} imdocker_req_t; + +typedef struct docker_container_info_s { + uchar *name; + uchar *image_id; + uint64_t created; + /* json string container labels */ + uchar *json_str_labels; +} docker_container_info_t; + +typedef struct docker_cont_logs_inst_s { + char *id; + char short_id[12]; + docker_container_info_t *container_info; + docker_cont_logs_req_t *logsReq; + uchar *start_regex; + regex_t start_preg; /* compiled version of start_regex */ + uint32_t prevSegEnd; +} docker_cont_logs_inst_t; + +typedef struct docker_cont_log_instances_s { + struct hashtable* ht_container_log_insts; + pthread_mutex_t mut; + CURLM *curlm; + /* track the latest created container */ + uint64_t last_container_created; + uchar *last_container_id; + time_t time_started; +} docker_cont_log_instances_t; + +/* FORWARD DEFINITIONS */ + +/* imdocker_buf_t */ +static rsRetVal imdockerBufNew(imdocker_buf_t **ppThis); +static void imdockerBufDestruct(imdocker_buf_t *pThis); + +/* docker_cont_logs_buf_t */ +static rsRetVal dockerContLogsBufNew(docker_cont_logs_buf_t **ppThis); +static void dockerContLogsBufDestruct(docker_cont_logs_buf_t *pThis); +static rsRetVal dockerContLogsBufWrite(docker_cont_logs_buf_t *pThis, const uchar *pdata, + size_t write_size); + +/* imdocker_req_t */ +static rsRetVal imdockerReqNew(imdocker_req_t **ppThis); +static void imdockerReqDestruct(imdocker_req_t *pThis); + +/* docker_cont_logs_req_t */ +static rsRetVal dockerContLogsReqNew(docker_cont_logs_req_t **ppThis, SubmitMsgFuncPtr submitMsg); +static void dockerContLogsReqDestruct(docker_cont_logs_req_t *pThis); + +/* docker_cont_logs_inst_t */ +static rsRetVal +dockerContLogsInstNew(docker_cont_logs_inst_t **ppThis, const char* id, + docker_container_info_t *container_info, SubmitMsgFuncPtr submitMsg); + +static void dockerContLogsInstDestruct(docker_cont_logs_inst_t *pThis); +static rsRetVal dockerContLogsInstSetUrlById (sbool isInit, docker_cont_logs_inst_t *pThis, + CURLM *curlm, const char* containerId); + +/* docker_cont_log_instances_t */ +static rsRetVal dockerContLogReqsNew(docker_cont_log_instances_t **ppThis); +static rsRetVal dockerContLogReqsDestruct(docker_cont_log_instances_t *pThis); +static rsRetVal dockerContLogReqsGet(docker_cont_log_instances_t *pThis, + docker_cont_logs_inst_t** ppContLogsInst, const char *id); +static rsRetVal dockerContLogReqsPrint(docker_cont_log_instances_t *pThis); +static rsRetVal dockerContLogReqsAdd(docker_cont_log_instances_t *pThis, + docker_cont_logs_inst_t *pContLogsReqInst); +static rsRetVal dockerContLogReqsRemove(docker_cont_log_instances_t *pThis, const char *id); + +/* docker_container_info_t */ +static rsRetVal dockerContainerInfoNew(docker_container_info_t **pThis); +static void dockerContainerInfoDestruct(docker_container_info_t *pThis); + +/* utility functions */ +static CURLcode docker_get(imdocker_req_t *req, const char* url); +static char* dupDockerContainerName(const char* pname); +static rsRetVal SubmitMsg(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, + const uchar* pszTag); +/* support multi-line */ +static rsRetVal +SubmitMsg2(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar* pszTag); +static size_t imdocker_container_list_curlCB(void *data, size_t size, size_t nmemb, void *buffer); +static size_t imdocker_container_logs_curlCB(void *data, size_t size, size_t nmemb, void *buffer); +static sbool get_stream_info(const uchar* data, size_t size, int8_t *stream_type, size_t *payload_size); +static int8_t is_valid_stream_type(int8_t stream_type); + +/* Module static data */ +DEF_IMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(prop) +DEFobjCurrIf(parser) +DEFobjCurrIf(datetime) +DEFobjCurrIf(statsobj) + +statsobj_t *modStats; +STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit) +STATSCOUNTER_DEF(ctrLostRatelimit, mutCtrLostRatelimit) +STATSCOUNTER_DEF(ctrCurlError, mutCtrCurlError) + +const char* DFLT_dockerAPIUnixSockAddr = "/var/run/docker.sock"; +const char* DFLT_dockerAPIAdd = "http://localhost:2375"; +const char* DFLT_apiVersionStr = "v1.27"; +const char* DFLT_listContainersOptions = ""; +const char* DFLT_getContainerLogOptions = "timestamps=0&follow=1&stdout=1&stderr=1&tail=1"; +const char* DFLT_getContainerLogOptionsWithoutTail = "timestamps=0&follow=1&stdout=1&stderr=1"; + +/* Overall module configuration structure here. */ +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + uchar *apiVersionStr; + uchar *listContainersOptions; + uchar *getContainerLogOptions; + uchar *getContainerLogOptionsWithoutTail; + int iPollInterval; /* in seconds */ + uchar *dockerApiUnixSockAddr; + uchar *dockerApiAddr; + sbool retrieveNewLogsFromStart; + int containersLimit; + int trimLineOverBytes; + int iDfltSeverity; + int iDfltFacility; + sbool bEscapeLf; +}; + +static modConfData_t *loadModConf = NULL; +static modConfData_t *runModConf = NULL; + +static prop_t *pInputName = NULL; /* our inputName currently is always "imdocker", and this will hold it */ +static prop_t *pLocalHostIP = NULL; /* a pseudo-constant propterty for 127.0.0.1 */ + +static ratelimit_t *ratelimiter = NULL; + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + { "apiversionstr", eCmdHdlrString, 0 }, + { "dockerapiunixsockaddr", eCmdHdlrString, 0 }, + { "dockerapiaddr", eCmdHdlrString, 0 }, + { "listcontainersoptions", eCmdHdlrString, 0 }, + { "getcontainerlogoptions", eCmdHdlrString, 0 }, + { "pollinginterval", eCmdHdlrPositiveInt, 0 }, + { "retrievenewlogsfromstart", eCmdHdlrBinary, 0 }, + { "trimlineoverbytes", eCmdHdlrPositiveInt, 0 }, + { "defaultseverity", eCmdHdlrSeverity, 0 }, + { "defaultfacility", eCmdHdlrFacility, 0 }, + { "escapelf", eCmdHdlrBinary, 0 }, +}; + +static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr + }; + +static int bLegacyCnfModGlobalsPermitted; /* are legacy module-global config parameters permitted? */ + +/* imdocker specific functions */ +static rsRetVal +imdockerBufNew(imdocker_buf_t **ppThis) { + DEFiRet; + + imdocker_buf_t *pThis = (imdocker_buf_t*) calloc(1, sizeof(imdocker_buf_t)); + if (!pThis) { return RS_RET_OUT_OF_MEMORY; } + *ppThis = pThis; + + RETiRet; +} + +static void +imdockerBufDestruct(imdocker_buf_t *pThis) { + if (pThis) { + if (pThis->data) { + free(pThis->data); + pThis->data = NULL; + } + free(pThis); + } +} + +static rsRetVal +dockerContLogsBufNew(docker_cont_logs_buf_t **ppThis) { + DEFiRet; + + docker_cont_logs_buf_t *pThis = (docker_cont_logs_buf_t*) calloc(1, sizeof(docker_cont_logs_buf_t)); + if (pThis && (iRet = imdockerBufNew(&pThis->buf)) == RS_RET_OK) { + pThis->stream_type = dst_invalid; + pThis->bytes_remaining = 0; + *ppThis = pThis; + } else { + dockerContLogsBufDestruct(pThis); + } + + RETiRet; +} + +static void +dockerContLogsBufDestruct(docker_cont_logs_buf_t *pThis) { + if (pThis) { + if (pThis->buf) { + imdockerBufDestruct(pThis->buf); + } + free(pThis); + } +} + +static rsRetVal +dockerContLogsBufWrite(docker_cont_logs_buf_t *const pThis, const uchar *const pdata, const size_t write_size) { + DEFiRet; + + imdocker_buf_t *const mem = pThis->buf; + if (mem->len + write_size + 1 > mem->data_size) { + uchar *const pbuf = realloc(mem->data, mem->len + write_size + 1); + if(pbuf == NULL) { + LogError(errno, RS_RET_ERR, "%s() - realloc failed!\n", __FUNCTION__); + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + mem->data = pbuf; + mem->data_size = mem->len+ write_size + 1; + } + /* copy the bytes, and advance pdata */ + memcpy(&(mem->data[mem->len]), pdata, write_size); + mem->len += write_size; + mem->data[mem->len] = '\0'; + + if (write_size > pThis->bytes_remaining) { + pThis->bytes_remaining = 0; + } else { + pThis->bytes_remaining -= write_size; + } + +finalize_it: + RETiRet; +} + +rsRetVal imdockerReqNew(imdocker_req_t **ppThis) { + DEFiRet; + + imdocker_req_t *pThis = (imdocker_req_t*) calloc(1, sizeof(imdocker_req_t)); + CHKmalloc(pThis); + pThis->curl = curl_easy_init(); + if (!pThis->curl) { + ABORT_FINALIZE(RS_RET_ERR); + } + + CHKiRet(imdockerBufNew(&(pThis->buf))); + *ppThis = pThis; + +finalize_it: + if (iRet != RS_RET_OK && pThis) { + imdockerReqDestruct(pThis); + } + RETiRet; +} + +void imdockerReqDestruct(imdocker_req_t *pThis) { + if (pThis) { + if (pThis->buf) { + imdockerBufDestruct(pThis->buf); + } + + if (pThis->curl) { + curl_easy_cleanup(pThis->curl); + pThis->curl = NULL; + } + free(pThis); + } +} + +static rsRetVal +dockerContLogsReqNew(docker_cont_logs_req_t **ppThis, SubmitMsgFuncPtr submitMsg) { + DEFiRet; + + docker_cont_logs_req_t *pThis = (docker_cont_logs_req_t*) calloc(1, sizeof(docker_cont_logs_req_t)); + CHKmalloc(pThis); + pThis->submitMsg = submitMsg; + pThis->curl = curl_easy_init(); + if (!pThis->curl) { + ABORT_FINALIZE(RS_RET_ERR); + } + + for (int i = 0; i < dst_stream_type_count; i ++) { + CHKiRet(dockerContLogsBufNew(&pThis->data_bufs[i])); + } + + *ppThis = pThis; + +finalize_it: + if (iRet != RS_RET_OK) { + if (pThis) { + dockerContLogsReqDestruct(pThis); + } + } + RETiRet; +} + +static void +dockerContLogsReqDestruct(docker_cont_logs_req_t *pThis) { + if (pThis) { + for (int i = 0; i < dst_stream_type_count; i++) { + dockerContLogsBufDestruct(pThis->data_bufs[i]); + } + + if (pThis->curl) { + curl_easy_cleanup(pThis->curl); + pThis->curl=NULL; + } + + free(pThis); + } +} + +/** + * debugging aide + */ +static rsRetVal +dockerContLogsInstPrint(docker_cont_logs_inst_t * pThis) { + DEFiRet; + DBGPRINTF("\t container id: %s\n", pThis->id); + char* pUrl = NULL; + curl_easy_getinfo(pThis->logsReq->curl, CURLINFO_EFFECTIVE_URL, &pUrl); + DBGPRINTF("\t container url: %s\n", pUrl); + + RETiRet; +} + +static void +dockerContLogsInstDestruct(docker_cont_logs_inst_t *pThis) { + if (pThis) { + if (pThis->id) { + free((void*)pThis->id); + } + if (pThis->container_info) { + dockerContainerInfoDestruct(pThis->container_info); + } + if (pThis->logsReq) { + dockerContLogsReqDestruct(pThis->logsReq); + } + if (pThis->start_regex) { + free(pThis->start_regex); + regfree(&pThis->start_preg); + } + free(pThis); + } +} + +static rsRetVal +parseLabels(docker_cont_logs_inst_t *inst, const uchar* json) { + DEFiRet; + + /* parse out if we need to do special handling for mult-line */ + DBGPRINTF("%s() - parsing json=%s\n", __FUNCTION__, json); + + struct fjson_object *json_obj = fjson_tokener_parse((const char*)json); + struct fjson_object_iterator it = fjson_object_iter_begin(json_obj); + struct fjson_object_iterator itEnd = fjson_object_iter_end(json_obj); + while (!fjson_object_iter_equal(&it, &itEnd)) { + if (Debug) { + DBGPRINTF("%s - \t%s: '%s'\n", + __FUNCTION__, + fjson_object_iter_peek_name(&it), + fjson_object_get_string(fjson_object_iter_peek_value(&it))); + } + + if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_LABEL_KEY_STARTREGEX) == 0) { + inst->start_regex = (uchar*)strdup(fjson_object_get_string(fjson_object_iter_peek_value(&it))); + // compile the regex for future use. + int err = regcomp(&inst->start_preg, fjson_object_get_string(fjson_object_iter_peek_value(&it)), + REG_EXTENDED); + if (err != 0) { + char errbuf[512]; + regerror(err, &inst->start_preg, errbuf, sizeof(errbuf)); + LogError(0, err, "%s() - error in startregex compile: %s", __FUNCTION__, errbuf); + ABORT_FINALIZE(RS_RET_ERR); + } + } + fjson_object_iter_next(&it); + } + +finalize_it: + if (json_obj) { + json_object_put(json_obj); + } + RETiRet; +} + +static rsRetVal +dockerContLogsInstNew(docker_cont_logs_inst_t **ppThis, const char* id, + docker_container_info_t *container_info, SubmitMsgFuncPtr submitMsg) { + DEFiRet; + + docker_cont_logs_inst_t *pThis = NULL; + CHKmalloc(pThis = calloc(1, sizeof(docker_cont_logs_inst_t))); + + pThis->id = strdup((char*)id); + strncpy((char*) pThis->short_id, id, sizeof(pThis->short_id)-1); + CHKiRet(dockerContLogsReqNew(&pThis->logsReq, submitMsg)); + /* make a copy */ + if (container_info) { + CHKiRet(dockerContainerInfoNew(&pThis->container_info)); + if (container_info->image_id) { + pThis->container_info->image_id = (uchar*)strdup((char*)container_info->image_id); + } + if (container_info->name) { + const char *pname = (const char*)container_info->name; + /* removes un-needed characters */ + pThis->container_info->name = (uchar*)dupDockerContainerName(pname); + } + if (container_info->json_str_labels) { + pThis->container_info->json_str_labels = + (uchar*)strdup((char*)container_info->json_str_labels); + } + pThis->container_info->created = container_info->created; + } + pThis->start_regex = NULL; + pThis->prevSegEnd = 0; + /* initialize based on labels found */ + if (pThis->container_info && pThis->container_info->json_str_labels) { + parseLabels(pThis, pThis->container_info->json_str_labels); + } + + *ppThis = pThis; + +finalize_it: + if (iRet != RS_RET_OK) { + if (pThis) { + dockerContLogsInstDestruct(pThis); + } + } + RETiRet; +} + +static rsRetVal +dockerContLogsInstSetUrl(docker_cont_logs_inst_t *pThis, CURLM *curlm, const char* pUrl) { + DEFiRet; + CURLcode ccode = CURLE_OK; + CURLMcode mcode = CURLM_OK; + + if (curlm) { + docker_cont_logs_req_t *req = pThis->logsReq; + if (!runModConf->dockerApiAddr) { + ccode = curl_easy_setopt(req->curl, CURLOPT_UNIX_SOCKET_PATH, + runModConf->dockerApiUnixSockAddr); + if (ccode != CURLE_OK) { + LogError(0, RS_RET_ERR, + "imdocker: curl_easy_setopt(CURLOPT_UNIX_SOCKET_PATH) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_ERR); + } + } + ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEFUNCTION, imdocker_container_logs_curlCB); + if (ccode != CURLE_OK) { + LogError(0, RS_RET_ERR, + "imdocker: curl_easy_setopt(CURLOPT_WRITEFUNCTION) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_ERR); + } + + ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEDATA, pThis); + if (ccode != CURLE_OK) { + LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_WRITEDATA) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_ERR); + } + + ccode = curl_easy_setopt(pThis->logsReq->curl, CURLOPT_URL, pUrl); + if (ccode != CURLE_OK) { + LogError(0, RS_RET_ERR, "imdocker: could not set url - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_ERR); + } + + ccode = curl_easy_setopt(pThis->logsReq->curl, CURLOPT_PRIVATE, pThis->id); + if (ccode != CURLE_OK) { + LogError(0, RS_RET_ERR, "imdocker: could not set private data - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_ERR); + } + + mcode = curl_multi_add_handle(curlm, pThis->logsReq->curl); + if (mcode != CURLM_OK) { + LogError(0, RS_RET_ERR, "imdocker: error curl_multi_add_handle ret- %d:%s\n", + mcode, curl_multi_strerror(mcode)); + ABORT_FINALIZE(RS_RET_ERR); + } + } + +finalize_it: + if (ccode != CURLE_OK) { + STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); + } + RETiRet; +} + +static rsRetVal +dockerContLogsInstSetUrlById (sbool isInit, docker_cont_logs_inst_t *pThis, CURLM *curlm, + const char* containerId) { + char url[256]; + const uchar* container_log_options = runModConf->getContainerLogOptionsWithoutTail; + + if (isInit || !runModConf->retrieveNewLogsFromStart) { + container_log_options = runModConf->getContainerLogOptions; + } + + const uchar* pApiAddr = (uchar*)"http:"; + if (runModConf->dockerApiAddr) { + pApiAddr = runModConf->dockerApiAddr; + } + + snprintf(url, sizeof(url), "%s/%s/containers/%s/logs?%s", + pApiAddr, runModConf->apiVersionStr, containerId, container_log_options); + DBGPRINTF("%s() - url: %s\n", __FUNCTION__, url); + + return dockerContLogsInstSetUrl(pThis, curlm, url); +} + +/* special destructor for hashtable object. */ +static void +dockerContLogReqsDestructForHashtable(void *pData) { + docker_cont_logs_inst_t *pThis = (docker_cont_logs_inst_t *) pData; + dockerContLogsInstDestruct(pThis); +} + +static rsRetVal +dockerContLogReqsNew(docker_cont_log_instances_t **ppThis) { + DEFiRet; + + docker_cont_log_instances_t *pThis = calloc(1, sizeof(docker_cont_log_instances_t)); + CHKmalloc(pThis); + CHKmalloc(pThis->ht_container_log_insts = + create_hashtable(7, hash_from_string, key_equals_string, + dockerContLogReqsDestructForHashtable)); + + CHKiConcCtrl(pthread_mutex_init(&pThis->mut, NULL)); + + pThis->curlm = curl_multi_init(); + if (!pThis->curlm) { + ABORT_FINALIZE(RS_RET_ERR); + } + + *ppThis = pThis; + +finalize_it: + if (iRet != RS_RET_OK) { + if (pThis) { + dockerContLogReqsDestruct(pThis); + } + } + RETiRet; +} + +static rsRetVal +dockerContLogReqsDestruct(docker_cont_log_instances_t *pThis) { + DEFiRet; + + if (pThis) { + if (pThis->ht_container_log_insts) { + pthread_mutex_lock(&pThis->mut); + hashtable_destroy(pThis->ht_container_log_insts, 1); + pthread_mutex_unlock(&pThis->mut); + } + if (pThis->last_container_id) { + free(pThis->last_container_id); + } + curl_multi_cleanup(pThis->curlm); + pthread_mutex_destroy(&pThis->mut); + free(pThis); + } + + RETiRet; +} + +/* NOTE: not thread safe - used internally to update container log requests */ +static rsRetVal +dockerContLogReqsGet(docker_cont_log_instances_t *pThis, + docker_cont_logs_inst_t** ppContLogsInst, const char *id) { + DEFiRet; + + if (ppContLogsInst && id) { + docker_cont_logs_inst_t *pSearchObj = hashtable_search(pThis->ht_container_log_insts, (void*)id); + if (!pSearchObj) { + return RS_RET_NOT_FOUND; + } + *ppContLogsInst = pSearchObj; + } + + RETiRet; +} + +/* debug print + * + * NOTE: not thread safe + * + */ +static rsRetVal +dockerContLogReqsPrint(docker_cont_log_instances_t *pThis) { + DEFiRet; + int count = 0; + + count = hashtable_count(pThis->ht_container_log_insts); + if (count) { + int ret = 0; + struct hashtable_itr *itr = hashtable_iterator(pThis->ht_container_log_insts); + + DBGPRINTF("%s() - All container instances, count=%d...\n", __FUNCTION__, count); + do { + docker_cont_logs_inst_t *pObj = hashtable_iterator_value(itr); + dockerContLogsInstPrint(pObj); + ret = hashtable_iterator_advance(itr); + } while (ret); + free (itr); + DBGPRINTF("End of container instances.\n"); + } + + RETiRet; +} + +/* NOTE: not thread safe */ +static rsRetVal +dockerContLogReqsAdd(docker_cont_log_instances_t *pThis, + docker_cont_logs_inst_t *pContLogsReqInst) +{ + DEFiRet; + if (!pContLogsReqInst) { + return RS_RET_ERR; + } + + uchar *keyName = (uchar*)strdup((char*)pContLogsReqInst->id); + + if (keyName) { + docker_cont_logs_inst_t *pFind; + if (RS_RET_NOT_FOUND == dockerContLogReqsGet(pThis, &pFind, (void*)keyName)) { + if (!hashtable_insert(pThis->ht_container_log_insts, keyName, pContLogsReqInst)) { + ABORT_FINALIZE(RS_RET_ERR); + } + keyName = NULL; + } + } +finalize_it: + free(keyName); + RETiRet; +} + +static rsRetVal +dockerContLogReqsRemove(docker_cont_log_instances_t *pThis, const char *id) { + DEFiRet; + + if (pThis && id) { + CHKiConcCtrl(pthread_mutex_lock(&pThis->mut)); + docker_cont_logs_inst_t *pRemoved = + hashtable_remove(pThis->ht_container_log_insts, (void*)id); + pthread_mutex_unlock(&pThis->mut); + if (pRemoved) { + dockerContLogsInstDestruct(pRemoved); + } else { + iRet = RS_RET_NOT_FOUND; + } + } +finalize_it: + RETiRet; +} + +static rsRetVal +dockerContainerInfoNew(docker_container_info_t **ppThis) { + DEFiRet; + docker_container_info_t* pThis = calloc(1, sizeof(docker_container_info_t)); + CHKmalloc(pThis); + *ppThis = pThis; + +finalize_it: + RETiRet; +} + +static void +dockerContainerInfoDestruct(docker_container_info_t *pThis) { + if (pThis) { + if (pThis->image_id) { free(pThis->image_id); } + if (pThis->name) { free(pThis->name); } + if (pThis->json_str_labels) { free(pThis->json_str_labels); } + free(pThis); + } +} + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + + dbgprintf("imdocker: beginCnfLoad\n"); + + loadModConf = pModConf; + pModConf->pConf = pConf; + + /* init our settings */ + loadModConf->iPollInterval = DFLT_pollingInterval; /* in seconds */ + loadModConf->retrieveNewLogsFromStart = DFLT_retrieveNewLogsFromStart; + loadModConf->containersLimit = DFLT_containersLimit; + loadModConf->trimLineOverBytes = DFLT_trimLineOverBytes; + loadModConf->bEscapeLf = DFLT_bEscapeLF; + + /* Use the default url */ + loadModConf->apiVersionStr = NULL; + loadModConf->dockerApiUnixSockAddr = NULL; + loadModConf->dockerApiAddr = NULL; + loadModConf->listContainersOptions = NULL; + loadModConf->getContainerLogOptions = NULL; + loadModConf->getContainerLogOptionsWithoutTail = NULL; + loadModConf->iDfltFacility = DFLT_FACILITY; + loadModConf->iDfltSeverity = DFLT_SEVERITY; +ENDbeginCnfLoad + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module " + "config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if (Debug) { + dbgprintf("module (global) param blk for imdocker:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(i = 0 ; i < modpblk.nParams ; ++i) { + dbgprintf("%s() - iteration %d\n", __FUNCTION__,i); + dbgprintf("%s() - modpblk descr: %s\n", __FUNCTION__, modpblk.descr[i].name); + if(!pvals[i].bUsed) + continue; + if(!strcmp(modpblk.descr[i].name, "pollinginterval")) { + loadModConf->iPollInterval = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "containterlimit")) { + loadModConf->containersLimit = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "trimlineoverbytes")) { + loadModConf->trimLineOverBytes = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "listcontainersoptions")) { + loadModConf->listContainersOptions = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "getcontainerlogoptions")) { + loadModConf->getContainerLogOptions = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + /* also intialize the non-tail version */ + size_t offset = 0; + char buf[256]; + size_t buf_size = sizeof(buf); + strncpy(buf, (char*)loadModConf->getContainerLogOptions, buf_size-1); + size_t option_str_len = strlen((char*)loadModConf->getContainerLogOptions); + uchar *option_str = calloc(1, option_str_len); + CHKmalloc(option_str); + + const char *search_str = "tail="; + size_t search_str_len = strlen(search_str); + char *token = strtok(buf, "&"); + + while (token != NULL) { + if (strncmp(token, search_str, search_str_len) == 0) { + token = strtok(NULL, "&"); + continue; + } + int len = strlen(token); + if (offset + len + 1 >= option_str_len) { + break; + } + int bytes = snprintf((char*)option_str + offset, + (option_str_len - offset), "%s&", token); + if (bytes <= 0) { + break; + } + offset += bytes; + token = strtok(NULL, "&"); + } + loadModConf->getContainerLogOptionsWithoutTail = option_str; + } else if(!strcmp(modpblk.descr[i].name, "dockerapiunixsockaddr")) { + loadModConf->dockerApiUnixSockAddr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "dockerapiaddr")) { + loadModConf->dockerApiAddr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "apiversionstr")) { + loadModConf->apiVersionStr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "retrievenewlogsfromstart")) { + loadModConf->retrieveNewLogsFromStart = (sbool) pvals[i].val.d.n; + } else if (!strcmp(modpblk.descr[i].name, "defaultseverity")) { + loadModConf->iDfltSeverity = (int) pvals[i].val.d.n; + } else if (!strcmp(modpblk.descr[i].name, "defaultfacility")) { + loadModConf->iDfltFacility = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "escapelf")) { + loadModConf->bEscapeLf = (sbool) pvals[i].val.d.n; + } else { + LogError(0, RS_RET_INVALID_PARAMS, + "imdocker: program error, non-handled " + "param '%s' in setModCnf\n", modpblk.descr[i].name); + } + } + + /* disable legacy module-global config directives */ + bLegacyCnfModGlobalsPermitted = 0; + +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + if (!loadModConf->dockerApiUnixSockAddr) { + loadModConf->dockerApiUnixSockAddr = (uchar*) strdup(DFLT_dockerAPIUnixSockAddr); + } + if (!loadModConf->apiVersionStr) { + loadModConf->apiVersionStr = (uchar*) strdup(DFLT_apiVersionStr); + } + if (!loadModConf->listContainersOptions) { + loadModConf->listContainersOptions = (uchar*) strdup(DFLT_listContainersOptions); + } + if (!loadModConf->getContainerLogOptions) { + loadModConf->getContainerLogOptions = (uchar*) strdup(DFLT_getContainerLogOptions); + } +if (!loadModConf->getContainerLogOptionsWithoutTail) { + loadModConf->getContainerLogOptionsWithoutTail = + (uchar*) strdup(DFLT_getContainerLogOptionsWithoutTail); + } + runModConf = loadModConf; + + /* support statistics gathering */ + CHKiRet(statsobj.Construct(&modStats)); + CHKiRet(statsobj.SetName(modStats, UCHAR_CONSTANT("imdocker"))); + CHKiRet(statsobj.SetOrigin(modStats, UCHAR_CONSTANT("imdocker"))); + + STATSCOUNTER_INIT(ctrSubmit, mutCtrSubmit); + CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("submitted"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrSubmit)); + + STATSCOUNTER_INIT(ctrLostRatelimit, mutCtrLostRatelimit); + CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("ratelimit.discarded"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrLostRatelimit)); + + STATSCOUNTER_INIT(ctrCurlError, mutCtrCurlError); + CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("curl.errors"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrCurlError)); + + CHKiRet(statsobj.ConstructFinalize(modStats)); + /* end stats */ +finalize_it: +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf + if (loadModConf->dockerApiUnixSockAddr) { + free(loadModConf->dockerApiUnixSockAddr); + } + if (loadModConf->dockerApiAddr) { + free(loadModConf->dockerApiAddr); + } + if (loadModConf->apiVersionStr) { + free(loadModConf->apiVersionStr); + } + if (loadModConf->getContainerLogOptions) { + free(loadModConf->getContainerLogOptions); + } + if (loadModConf->getContainerLogOptionsWithoutTail) { + free(loadModConf->getContainerLogOptionsWithoutTail); + } + if (loadModConf->listContainersOptions) { + free(loadModConf->listContainersOptions); + } + statsobj.Destruct(&modStats); +ENDfreeCnf + +static rsRetVal +addDockerMetaData(const uchar* container_id, docker_container_info_t* pinfo, smsg_t *pMsg) { + const uchar *names[4] = { + (const uchar*) DOCKER_CONTAINER_ID_PARSE_NAME, + (const uchar*) DOCKER_CONTAINER_NAMES_PARSE_NAME, + (const uchar*) DOCKER_CONTAINER_IMAGEID_PARSE_NAME, + (const uchar*) DOCKER_CONTAINER_LABELS_PARSE_NAME + }; + + const uchar * empty_str= (const uchar*) ""; + const uchar *id = container_id ? container_id : empty_str; + const uchar *name = pinfo->name ? pinfo->name : empty_str; + const uchar *image_id = pinfo->image_id ? pinfo->image_id : empty_str; + const uchar *json_str_labels = pinfo->json_str_labels ? pinfo->json_str_labels : empty_str; + + const uchar *values[4] = { + id, + name, + image_id, + json_str_labels + }; + + return msgAddMultiMetadata(pMsg, names, values, 4); +} + +static rsRetVal +enqMsg(docker_cont_logs_inst_t *pInst, uchar *msg, size_t len, const uchar *pszTag, + int facility, int severity, struct timeval *tp) +{ + struct syslogTime st; + smsg_t *pMsg; + DEFiRet; + + if (!msg) { + return RS_RET_ERR; + } + + if (tp == NULL) { + CHKiRet(msgConstruct(&pMsg)); + } else { + datetime.timeval2syslogTime(tp, &st, TIME_IN_LOCALTIME); + CHKiRet(msgConstructWithTime(&pMsg, &st, tp->tv_sec)); + } + MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); + MsgSetInputName(pMsg, pInputName); + MsgSetRawMsg(pMsg, (char*)msg, len); + + if (loadModConf->bEscapeLf) { + parser.SanitizeMsg(pMsg); + } else { + /* Perform some of the SanitizeMsg operations here - specifically: + * - remove NULL character at end of message. + * - drop trailing LFs. + * See SanitizeMsg() for more info. + */ + size_t lenMsg = pMsg->iLenRawMsg; + uchar *pszMsg = pMsg->pszRawMsg; + + if(pszMsg[lenMsg-1] == '\0') { + DBGPRINTF("dropped NULL at very end of message\n"); + lenMsg--; + } + + if(glbl.GetParserDropTrailingLFOnReception(loadModConf->pConf) + && lenMsg > 0 && pszMsg[lenMsg-1] == '\n') { + DBGPRINTF("dropped LF at very end of message (DropTrailingLF is set)\n"); + lenMsg--; + pszMsg[lenMsg] = '\0'; + } + pMsg->iLenRawMsg = lenMsg; + } + + MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ + MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); + if (pLocalHostIP) { MsgSetRcvFromIP(pMsg, pLocalHostIP); } + MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); + MsgSetTAG(pMsg, pszTag, ustrlen(pszTag)); + pMsg->iFacility = facility; + pMsg->iSeverity = severity; + + /* docker container metadata */ + addDockerMetaData((const uchar*)pInst->short_id, pInst->container_info, pMsg); + + const char *name = (const char*)pInst->container_info->name; + DBGPRINTF("imdocker: %s - %s:%s\n", __FUNCTION__, name, msg); + CHKiRet(ratelimitAddMsg(ratelimiter, NULL, pMsg)); + STATSCOUNTER_INC(ctrSubmit, mutCtrSubmit); + +finalize_it: + if (iRet == RS_RET_DISCARDMSG) + STATSCOUNTER_INC(ctrLostRatelimit, mutCtrLostRatelimit) + + RETiRet; +} + +static int8_t +is_valid_stream_type(int8_t stream_type) { + return (dst_invalid < stream_type && stream_type < dst_stream_type_count); +} + +/* For use to get docker specific stream information */ +static sbool +get_stream_info(const uchar* data, size_t size, int8_t *stream_type, size_t *payload_size) { + if (size < 8 || !data || !stream_type || !payload_size) { + return 0; + } + const uchar* pdata = data; + *stream_type = pdata[0]; + pdata += 4; + uint32_t len = 0; + memcpy(&len, pdata, sizeof(len)); + *payload_size = ntohl(len); + return 1; +} +#ifdef ENABLE_DEBUG_BYTE_BUFFER +static void debug_byte_buffer(const uchar* data, size_t size) { + if (Debug) { + DBGPRINTF("%s() - ENTER, size=%lu\n", __FUNCTION__, size); + for (size_t i = 0; i < size; i++) { + DBGPRINTF("0x%02x,", data[i]); + } + DBGPRINTF("\n"); + } +} +#endif + +/** + * imdocker_container_list_curlCB + * + * Callback function for CURLOPT_WRITEFUNCTION to get + * the results of a docker api call to list all containers. + * + */ +static size_t +imdocker_container_list_curlCB(void *data, size_t size, size_t nmemb, void *buffer) { + DEFiRet; + + size_t realsize = size*nmemb; + uchar *pbuf=NULL; + imdocker_buf_t *mem = (imdocker_buf_t*)buffer; + + if ((pbuf = realloc(mem->data, mem->len + realsize + 1)) == NULL) { + LogError(errno, RS_RET_ERR, "%s() - realloc failed!\n", __FUNCTION__); + ABORT_FINALIZE(RS_RET_ERR); + } + + mem->data = pbuf; + mem->data_size = mem->len + realsize + 1; + + memcpy(&(mem->data[mem->len]), data, realsize); + mem->len += realsize; + mem->data[mem->len] = 0; + +#ifdef ENABLE_DEBUG_BYTE_BUFFER + debug_byte_buffer((const uchar*) data, realsize); +#endif +finalize_it: + if (iRet != RS_RET_OK) { + return 0; + } + return realsize; +} + +static rsRetVal +SubmitMultiLineMsg(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, + const uchar* pszTag, size_t len) { + DEFiRet; + + imdocker_buf_t *mem = (imdocker_buf_t*)pBufData->buf; + DBGPRINTF("%s() {type=%d, len=%u} %s\n", + __FUNCTION__, pBufData->stream_type, (unsigned int)mem->len, mem->data); + + uchar* message = (uchar*)mem->data; + int facility = loadModConf->iDfltFacility; + int severity = pBufData->stream_type == dst_stderr ? LOG_ERR : loadModConf->iDfltSeverity; + enqMsg(pInst, message, len, (const uchar*)pszTag, facility, severity, NULL); + + size_t size = mem->len - pInst->prevSegEnd; + memmove(mem->data, mem->data+pInst->prevSegEnd, size); + mem->data[len] = '\0'; + mem->len = size; + pBufData->bytes_remaining = 0; + + RETiRet; +} + +static rsRetVal +SubmitMsgWithStartRegex(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar* pszTag) { + imdocker_buf_t *mem = (imdocker_buf_t*)pBufData->buf; + /* must be null terminated string */ + assert(mem->data[mem->len] == 0 || mem->data[mem->len] == '\0'); + const char* thisLine = (const char*) mem->data; + + if (pInst->prevSegEnd) { + thisLine = (const char*) mem->data+pInst->prevSegEnd; + } + DBGPRINTF("prevSeg: %d, thisLine: '%s'\n", pInst->prevSegEnd, thisLine); + DBGPRINTF("line(s) so far: '%s'\n", mem->data); + + /* check if this line is a start of multi-line message */ + regex_t *start_preg = (pInst->start_regex == NULL) ? NULL : &pInst->start_preg; + const int isStartMatch = start_preg ? + !regexec(start_preg, (char*)thisLine, 0, NULL, 0) : 0; + + if (isStartMatch && pInst->prevSegEnd != 0) { + SubmitMultiLineMsg(pInst, pBufData, pszTag, pInst->prevSegEnd); + pInst->prevSegEnd = 0; + FINALIZE; + } else { + /* just continue parsing using same buffer */ + pInst->prevSegEnd = mem->len; + } + +finalize_it: + return RS_RET_OK; +} + +static rsRetVal +SubmitMsg2(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar* pszTag) { + imdocker_buf_t *mem = (imdocker_buf_t*)pBufData->buf; + DBGPRINTF("%s() - {type=%d, len=%u} %s\n", + __FUNCTION__, pBufData->stream_type, (unsigned int)mem->len, mem->data); + + if (pInst->start_regex) { + SubmitMsgWithStartRegex(pInst, pBufData, pszTag); + } else { + SubmitMsg(pInst, pBufData, pszTag); + } + return RS_RET_OK; +} + +static rsRetVal +SubmitMsg(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar* pszTag) { + imdocker_buf_t *mem = (imdocker_buf_t*)pBufData->buf; + DBGPRINTF("%s() - {type=%d, len=%u} %s\n", + __FUNCTION__, pBufData->stream_type, (unsigned int)mem->len, mem->data); + + uchar* message = mem->data; + int facility = loadModConf->iDfltFacility; + int severity = pBufData->stream_type == dst_stderr ? LOG_ERR : loadModConf->iDfltSeverity; + enqMsg(pInst, message, mem->len, (const uchar*)pszTag, facility, severity, NULL); + + /* clear existing buffer. */ + mem->len = 0; + memset(mem->data, 0, mem->data_size); + pBufData->bytes_remaining = 0; + + return RS_RET_OK; +} + +/** imdocker_container_logs_curlCB + * + * Callback function for CURLOPT_WRITEFUNCTION, gets container logs + * + * The main container log stream handler. This function is registerred with curl to + * as callback to handle container log streaming. It follows the docker stream protocol + * as described in the docker container logs api. As per docker's api documentation, + * Docker Stream format: + * When the TTY setting is disabled in POST /containers/create, the stream over the + * hijacked connected is multiplexed to separate out stdout and stderr. The stream + * consists of a series of frames, each containing a header and a payload. + * + * The header contains the information which the stream writes (stdout or stderr). It also + * contains the size of the associated frame encoded in the last four bytes (uint32). + * + * It is encoded on the first eight bytes like this: + * + * header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4} + * STREAM_TYPE can be: + * 0: stdin (is written on stdout) + * 1: stdout + * 2: stderr + * + * Docker sends out data in 16KB sized frames, however with the addition of a header + * of 8 bytes, a frame may be split into 2 chunks by curl. The 2nd chunk will only + * contain enough data to complete the frame (8 leftever bytes). Including the header, + * this amounts to 16 bytes; 8 bytes for the header, and 8 bytes for the remaining frame + * data. + * + */ +static size_t +imdocker_container_logs_curlCB(void *data, size_t size, size_t nmemb, void *buffer) { + DEFiRet; + + const uint8_t frame_size = 8; + const char imdocker_eol_char = '\n'; + int8_t stream_type = dst_invalid; + + docker_cont_logs_inst_t* pInst = (docker_cont_logs_inst_t*) buffer; + docker_cont_logs_req_t* req = pInst->logsReq; + + size_t realsize = size*nmemb; + const uchar* pdata = data; + size_t write_size = 0; + +#ifdef ENABLE_DEBUG_BYTE_BUFFER + debug_byte_buffer((const uchar*) data, realsize); +#endif + + if (req->data_bufs[dst_stdout]->bytes_remaining || req->data_bufs[dst_stderr]->bytes_remaining) { + /* on continuation, stream types should matches with previous */ + if (req->data_bufs[dst_stdout]->bytes_remaining) { + if (req->data_bufs[dst_stderr]->bytes_remaining != 0) { + ABORT_FINALIZE(RS_RET_ERR); + } + } else if (req->data_bufs[dst_stderr]->bytes_remaining) { + if (req->data_bufs[dst_stdout]->bytes_remaining != 0) { + ABORT_FINALIZE(RS_RET_ERR); + } + } + + stream_type = req->data_bufs[dst_stdout]->bytes_remaining ? dst_stdout : dst_stderr; + docker_cont_logs_buf_t *pDataBuf = req->data_bufs[stream_type]; + + /* read off the remaining bytes */ + DBGPRINTF("Chunk continuation, remaining bytes: type: %d, " + "bytes remaining: %u, realsize: %u, data pos: %u\n", + stream_type, (unsigned int)pDataBuf->bytes_remaining, + (unsigned int)realsize, (unsigned int)pDataBuf->buf->len); + + write_size = MIN(pDataBuf->bytes_remaining, realsize); + CHKiRet(dockerContLogsBufWrite(pDataBuf, pdata, write_size)); + + /* submit it */ + if (pDataBuf->bytes_remaining == 0) { + imdocker_buf_t *mem = pDataBuf->buf; + if (mem->data[mem->len-1] == imdocker_eol_char) { + const char* szContainerId = NULL; + CURLcode ccode; + if(CURLE_OK != (ccode = curl_easy_getinfo(req->curl, + CURLINFO_PRIVATE, + &szContainerId))) { + LogError(0, RS_RET_ERR, + "imdocker: could not get private data req[%p] - %d:%s\n", + req->curl, ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_ERR); + } + req->submitMsg(pInst, pDataBuf, (const uchar*)DOCKER_TAG_NAME); + } + } + + pdata += write_size; + } + + /* not enough room left */ + if ((size_t)(pdata - (const uchar*)data) >= realsize) { + return (pdata - (const uchar*)data); + } + + size_t payload_size = 0; + const uchar* pread = pdata + frame_size; + docker_cont_logs_buf_t* pDataBuf = NULL; + + if (get_stream_info(pdata, realsize, &stream_type, &payload_size) + && is_valid_stream_type(stream_type)) { + pDataBuf = req->data_bufs[stream_type]; + pDataBuf->stream_type = stream_type; + pDataBuf->bytes_remaining = payload_size; + write_size = MIN(payload_size, realsize - frame_size); + } else { + /* copy all the data and submit to prevent data loss */ + stream_type = req->data_bufs[dst_stderr]->bytes_remaining ? dst_stderr : dst_stdout; + + pDataBuf = req->data_bufs[stream_type]; + pDataBuf->stream_type = stream_type; + + /* just write everything out */ + pDataBuf->bytes_remaining = 0; + write_size = realsize; + pread = pdata; + } + + /* allocate the expected payload size */ + CHKiRet(dockerContLogsBufWrite(pDataBuf, pread, write_size)); + if (pDataBuf->bytes_remaining == 0) { + DBGPRINTF("%s() - write size is same as payload_size\n", __FUNCTION__); + req->submitMsg(pInst, pDataBuf, (const uchar*)DOCKER_TAG_NAME); + } + +finalize_it: + if (iRet != RS_RET_OK) { + return 0; + } + return realsize; +} + +CURLcode docker_get(imdocker_req_t *req, const char* url) { + CURLcode ccode; + + if (!runModConf->dockerApiAddr) { + if ((ccode = curl_easy_setopt(req->curl, CURLOPT_UNIX_SOCKET_PATH, runModConf->dockerApiUnixSockAddr)) + != CURLE_OK) { + STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); + LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_UNIX_SOCKET_PATH) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + return ccode; + } + } + if ((ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEFUNCTION, imdocker_container_list_curlCB)) != CURLE_OK) { + STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); + LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_WRITEFUNCTION) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + return ccode; + } + if ((ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEDATA, req->buf)) != CURLE_OK) { + STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); + LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_WRITEDATA) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + return ccode; + } + + if ((ccode = curl_easy_setopt(req->curl, CURLOPT_URL, url)) != CURLE_OK) { + STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); + LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_URL) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + return ccode; + } + CURLcode response = curl_easy_perform(req->curl); + + return response; +} + +static char* +dupDockerContainerName(const char* pname) { + int len = strlen(pname); + if (len >= 2 && *pname == '/') { + /* skip '/' character */ + return strdup(pname+1); + } else { + return strdup(pname); + } +} + +static rsRetVal +process_json(sbool isInit, const char* json, docker_cont_log_instances_t *pInstances) { + DEFiRet; + struct fjson_object *json_obj = NULL; + int mut_locked = 0; + DBGPRINTF("%s() - parsing json=%s\n", __FUNCTION__, json); + + if (!pInstances) { + ABORT_FINALIZE(RS_RET_OK); + } + + json_obj = fjson_tokener_parse(json); + if (!json_obj || !fjson_object_is_type(json_obj, fjson_type_array)) { + ABORT_FINALIZE(RS_RET_OK); + } + + int length = fjson_object_array_length(json_obj); + /* LOCK the update process. */ + CHKiConcCtrl(pthread_mutex_lock(&pInstances->mut)); + mut_locked = 1; + + for (int i = 0; i < length; i++) { + fjson_object* p_json_elm = json_object_array_get_idx(json_obj, i); + + DBGPRINTF("element: %d...\n", i); + if (p_json_elm) { + const char *containerId=NULL; + docker_container_info_t containerInfo = { + .name=NULL, + .image_id=NULL, + .created=0, + .json_str_labels=NULL + }; + + struct fjson_object_iterator it = fjson_object_iter_begin(p_json_elm); + struct fjson_object_iterator itEnd = fjson_object_iter_end(p_json_elm); + while (!fjson_object_iter_equal(&it, &itEnd)) { + if (Debug) { + DBGPRINTF("\t%s: '%s'\n", + fjson_object_iter_peek_name(&it), + fjson_object_get_string(fjson_object_iter_peek_value(&it))); + } + + if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_ID_PARSE_NAME) == 0) { + containerId = + fjson_object_get_string(fjson_object_iter_peek_value(&it)); + } else if (strcmp(fjson_object_iter_peek_name(&it), + DOCKER_CONTAINER_NAMES_PARSE_NAME) == 0) { + int names_array_length = + fjson_object_array_length(fjson_object_iter_peek_value(&it)); + if (names_array_length) { + fjson_object* names_elm = + json_object_array_get_idx(fjson_object_iter_peek_value(&it), 0); + containerInfo.name = (uchar*)fjson_object_get_string(names_elm); + } + } else if (strcmp(fjson_object_iter_peek_name(&it), + DOCKER_CONTAINER_IMAGEID_PARSE_NAME) == 0) { + containerInfo.image_id = + (uchar*)fjson_object_get_string( + fjson_object_iter_peek_value(&it) + ); + } else if (strcmp(fjson_object_iter_peek_name(&it), + DOCKER_CONTAINER_CREATED_PARSE_NAME) == 0) { + containerInfo.created = + fjson_object_get_int64( + fjson_object_iter_peek_value(&it) + ); + } else if (strcmp(fjson_object_iter_peek_name(&it), + DOCKER_CONTAINER_LABELS_PARSE_NAME) == 0) { + containerInfo.json_str_labels = + (uchar*) fjson_object_get_string( + fjson_object_iter_peek_value(&it) + ); + DBGPRINTF("labels: %s\n", containerInfo.json_str_labels); + } + fjson_object_iter_next(&it); + } + + if (containerId) { + docker_cont_logs_inst_t *pInst = NULL; + iRet = dockerContLogReqsGet(pInstances, &pInst, containerId); + if (iRet == RS_RET_NOT_FOUND) { +#ifdef USE_MULTI_LINE + if (dockerContLogsInstNew(&pInst, containerId, &containerInfo, SubmitMsg2) +#else + if (dockerContLogsInstNew(&pInst, containerId, &containerInfo, SubmitMsg) +#endif + == RS_RET_OK) { + if (pInstances->last_container_created < containerInfo.created) { + pInstances->last_container_created = containerInfo.created; + if (pInstances->last_container_id) { + free(pInstances->last_container_id); + } + pInstances->last_container_id = (uchar*)strdup(containerId); + DBGPRINTF("last_container_id updated: ('%s', %u)\n", + pInstances->last_container_id, + (unsigned)pInstances->last_container_created); + } + CHKiRet(dockerContLogsInstSetUrlById(isInit, pInst, + pInstances->curlm, containerId)); + CHKiRet(dockerContLogReqsAdd(pInstances, pInst)); + } + } + } + } + } + +finalize_it: + if (mut_locked) { + pthread_mutex_unlock(&pInstances->mut); + } + if (json_obj) { + json_object_put(json_obj); + } + RETiRet; +} + +static rsRetVal +getContainerIds(sbool isInit, docker_cont_log_instances_t *pInstances, const char* url) { + DEFiRet; + imdocker_req_t *req=NULL; + + CHKiRet(imdockerReqNew(&req)); + + CURLcode response = docker_get(req, url); + if (response != CURLE_OK) { + DBGPRINTF("%s() - curl response: %d\n", __FUNCTION__, response); + ABORT_FINALIZE(RS_RET_ERR); + } + + CHKiRet(process_json(isInit, (const char*)req->buf->data, pInstances)); + +finalize_it: + if (req) { + imdockerReqDestruct(req); + } + RETiRet; +} + +static rsRetVal +getContainerIdsAndAppend(sbool isInit, docker_cont_log_instances_t *pInstances) { + DEFiRet; + + char url[256]; + const uchar* pApiAddr = (uchar*)"http:"; + + if (runModConf->dockerApiAddr) { + pApiAddr = runModConf->dockerApiAddr; + } + + /* + * TODO: consider if we really need 'isInit' parameter. I suspect we don't need it + * and i'm almost certain Travis CI will complain its not used. + */ + if (pInstances->last_container_id) { + snprintf(url, sizeof(url), "%s/%s/containers/json?%s&filters={\"since\":[\"%s\"]}", + pApiAddr, runModConf->apiVersionStr, runModConf->listContainersOptions, + pInstances->last_container_id); + } else { + snprintf(url, sizeof(url), "%s/%s/containers/json?%s", + pApiAddr, runModConf->apiVersionStr, runModConf->listContainersOptions); + } + DBGPRINTF("listcontainers url: %s\n", url); + + CHKiRet(getContainerIds(isInit, pInstances, (const char*)url)); + if (Debug) { dockerContLogReqsPrint(pInstances); } + +finalize_it: + RETiRet; +} + +static void +cleanupCompletedContainerRequests(docker_cont_log_instances_t *pInstances) { + // clean up + int rc=0, msgs_left=0; + CURLMsg *msg=NULL; + CURL *pCurl; + + while ((msg = curl_multi_info_read(pInstances->curlm, &msgs_left))) { + if (msg->msg == CURLMSG_DONE) { + pCurl = msg->easy_handle; + rc = msg->data.result; + if (rc != CURLE_OK) { + STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); + LogError(0, RS_RET_ERR, "imdocker: %s() - curl error code: %d:%s\n", + __FUNCTION__, rc, curl_multi_strerror(rc)); + continue; + } + + CURLcode ccode; + if (Debug) { + long http_status=0; + curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &http_status); + DBGPRINTF("http status: %lu\n", http_status); + } + curl_multi_remove_handle(pInstances->curlm, pCurl); + + const char* szContainerId = NULL; + if ((ccode = curl_easy_getinfo(pCurl, CURLINFO_PRIVATE, &szContainerId)) == CURLE_OK) { + DBGPRINTF("container disconnected: %s\n", szContainerId); + dockerContLogReqsRemove(pInstances, szContainerId); + DBGPRINTF("container removed...\n"); + } else { + LogError(0, RS_RET_ERR, "imdocker: private data not found " + "curl_easy_setopt(CURLINFO_PRIVATE) error - %d:%s\n", + ccode, curl_easy_strerror(ccode)); + STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); + } + } + } +} + +static rsRetVal +processAndPollContainerLogs(docker_cont_log_instances_t *pInstances) { + DEFiRet; + int count=0; + + count = hashtable_count(pInstances->ht_container_log_insts); + DBGPRINTF("%s() - container instances: %d\n", __FUNCTION__, count); + + int still_running=0; + + curl_multi_perform(pInstances->curlm, &still_running); + do { + int numfds = 0; + + int res = curl_multi_wait(pInstances->curlm, NULL, 0, 1000, &numfds); + if (res != CURLM_OK) { + LogError(0, RS_RET_ERR, "error: curl_multi_wait() numfds=%d, res=%d:%s\n", + numfds, res, curl_multi_strerror(res)); + return res; + } + + int prev_still_running = still_running; + curl_multi_perform(pInstances->curlm, &still_running); + + if (prev_still_running > still_running) { + cleanupCompletedContainerRequests(pInstances); + } + + } while (still_running && glbl.GetGlobalInputTermState() == 0); + + cleanupCompletedContainerRequests(pInstances); + + RETiRet; +} + +static void* +getContainersTask(void *pdata) { + docker_cont_log_instances_t *pInstances = (docker_cont_log_instances_t*) pdata; + + while(glbl.GetGlobalInputTermState() == 0) { + srSleep(runModConf->iPollInterval, 10); + getContainerIdsAndAppend(false, pInstances); + } + return pdata; +} + +/* This function is called to gather input. */ +BEGINrunInput + rsRetVal localRet = RS_RET_OK; + docker_cont_log_instances_t *pInstances=NULL; + pthread_t thrd_id; /* the worker's thread ID */ + pthread_attr_t thrd_attr; + int get_containers_thread_initialized = 0; + time_t now; +CODESTARTrunInput + datetime.GetTime(&now); + + CHKiRet(ratelimitNew(&ratelimiter, "imdocker", NULL)); + curl_global_init(CURL_GLOBAL_ALL); + localRet = dockerContLogReqsNew(&pInstances); + if (localRet != RS_RET_OK) { + return localRet; + } + pInstances->time_started = now; + + /* get all current containers now */ + CHKiRet(getContainerIdsAndAppend(true, pInstances)); + + /* using default stacksize */ + CHKiConcCtrl(pthread_attr_init(&thrd_attr)); + CHKiConcCtrl(pthread_create(&thrd_id, &thrd_attr, getContainersTask, pInstances)); + get_containers_thread_initialized = 1; + + while(glbl.GetGlobalInputTermState() == 0) { + CHKiRet(processAndPollContainerLogs(pInstances)); + if (glbl.GetGlobalInputTermState() == 0) { + /* exited from processAndPollContainerLogs, sleep before retrying */ + srSleep(1, 10); + } + } + +finalize_it: + if (get_containers_thread_initialized) { + pthread_kill(thrd_id, SIGTTIN); + pthread_join(thrd_id, NULL); + pthread_attr_destroy(&thrd_attr); + } + if (pInstances) { + dockerContLogReqsDestruct(pInstances); + } + if (ratelimiter) { + ratelimitDestruct(ratelimiter); + } +ENDrunInput + +BEGINwillRun +CODESTARTwillRun +ENDwillRun + +BEGINafterRun +CODESTARTafterRun +ENDafterRun + +BEGINmodExit +CODESTARTmodExit + if(pInputName != NULL) + prop.Destruct(&pInputName); + + if(pLocalHostIP != NULL) + prop.Destruct(&pLocalHostIP); + + objRelease(parser, CORE_COMPONENT); + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); + objRelease(statsobj, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURENonCancelInputTermination) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + CHKiRet(objUse(parser, CORE_COMPONENT)); + + DBGPRINTF("imdocker version %s initializing\n", VERSION); + + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imdocker"), sizeof("imdocker") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); + +ENDmodInit diff --git a/contrib/imhiredis/COPYING b/contrib/imhiredis/COPYING new file mode 100644 index 0000000..f44bd49 --- /dev/null +++ b/contrib/imhiredis/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/contrib/imhiredis/Makefile.am b/contrib/imhiredis/Makefile.am new file mode 100644 index 0000000..6528a19 --- /dev/null +++ b/contrib/imhiredis/Makefile.am @@ -0,0 +1,7 @@ +pkglib_LTLIBRARIES = imhiredis.la +imhiredis_la_SOURCES = imhiredis.c +imhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) +imhiredis_la_LDFLAGS = -module -avoid-version +imhiredis_la_LIBADD = $(HIREDIS_LIBS) + +EXTRA_DIST = diff --git a/contrib/imhiredis/Makefile.in b/contrib/imhiredis/Makefile.in new file mode 100644 index 0000000..fb3a3e2 --- /dev/null +++ b/contrib/imhiredis/Makefile.in @@ -0,0 +1,799 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/imhiredis +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +imhiredis_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_imhiredis_la_OBJECTS = imhiredis_la-imhiredis.lo +imhiredis_la_OBJECTS = $(am_imhiredis_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +imhiredis_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(imhiredis_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imhiredis_la-imhiredis.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imhiredis_la_SOURCES) +DIST_SOURCES = $(imhiredis_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING \ + README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = imhiredis.la +imhiredis_la_SOURCES = imhiredis.c +imhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) +imhiredis_la_LDFLAGS = -module -avoid-version +imhiredis_la_LIBADD = $(HIREDIS_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imhiredis/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/imhiredis/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +imhiredis.la: $(imhiredis_la_OBJECTS) $(imhiredis_la_DEPENDENCIES) $(EXTRA_imhiredis_la_DEPENDENCIES) + $(AM_V_CCLD)$(imhiredis_la_LINK) -rpath $(pkglibdir) $(imhiredis_la_OBJECTS) $(imhiredis_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imhiredis_la-imhiredis.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +imhiredis_la-imhiredis.lo: imhiredis.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imhiredis_la-imhiredis.lo -MD -MP -MF $(DEPDIR)/imhiredis_la-imhiredis.Tpo -c -o imhiredis_la-imhiredis.lo `test -f 'imhiredis.c' || echo '$(srcdir)/'`imhiredis.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imhiredis_la-imhiredis.Tpo $(DEPDIR)/imhiredis_la-imhiredis.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imhiredis.c' object='imhiredis_la-imhiredis.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imhiredis_la-imhiredis.lo `test -f 'imhiredis.c' || echo '$(srcdir)/'`imhiredis.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/imhiredis_la-imhiredis.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/imhiredis_la-imhiredis.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/imhiredis/README b/contrib/imhiredis/README new file mode 100644 index 0000000..70a9b31 --- /dev/null +++ b/contrib/imhiredis/README @@ -0,0 +1,81 @@ +Redis Input Plugin using hiredis library + +REQUIREMENTS: + +* hiredis ( https://github.com/redis/hiredis.git ) + +USAGE: + +This plugin has two current "modes" that it supports: + +1. "queue" +The queue mode will LPOP or RPOP your message from a redis list. +Following parameters are required: + - mode: Set mode to "queue" to enable the queue mode + - key: The key to xPOP on + - server: The name or IP address of the redis server + - port: The redis listening port + +Following parameters are optional: + - password: If set, the plugin will issue an "AUTH" command before calling xPOP + - uselpop: If set to "1", LPOP will be used instead of default RPOP + +Redis pipelining is used inside the worker thread. The dequeue batch size is configured with the "batchsize" parameter (default is 10). + +Imhiredis will query Redis every second to see if entries are in the list, if that's the case they will be dequeued +continuously by batches of "batchsize elements" until none remains. + +Due to its balance between polling interval and pipelining and its use of lists, this mode is quite performant and reliable. +However, due to the 1 second polling frequency, one may consider using the `subscribe` mode instead if very low latency is required. + +``` +module(load="imhiredis") + +input( + type="imhiredis" + mode="queue" + key="vulture" + server="127.0.0.1" + port="6379" + uselpop="1" + password="foobar" + batchsize="10" +) +``` + + + +2. "subscribe" +The subscribe mode will SUBSCRIBE to a redis channel. The "key" +parameter is required and will be used for the subscribe channel. + +Following parameters are required: + - mode: Set mode to "subscribe" to enable the subscribe mode + - key: The key to subscribe to (aka the "channel") + - server: The name or IP address of the redis server + - port: The redis listening port + +Following parameters are optional: + - password: If set, the plugin will issue an "AUTH" command before listening to a channel + - uselpop: If set to "1", LPOP will be used instead of default RPOP + + +``` +module(load="imhiredis") + +input( + type="imhiredis" + mode="subscribe" + key="vulture" + server="127.0.0.1" + port="6379" + password="foobar" + batchsize="10" +) +``` + + +TODO +* TLS support + + diff --git a/contrib/imhiredis/imhiredis.c b/contrib/imhiredis/imhiredis.c new file mode 100644 index 0000000..e1a8e1c --- /dev/null +++ b/contrib/imhiredis/imhiredis.c @@ -0,0 +1,2298 @@ +/* imhiredis.c +* Copyright 2021 aDvens +* +* This file is contrib for rsyslog. +* This input plugin is a log consumer from REDIS +* See README for doc +* +* +* This program is free software: you can redistribute it and/or +* modify it under the terms of the GNU Lesser 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this program. If not, see +* <http://www.gnu.org/licenses/>. +* +* Author: Jérémie Jourdin +* <jeremie.jourdin@advens.fr> +*/ + +#include "config.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <sys/uio.h> +#include <hiredis/hiredis.h> +#include <hiredis/async.h> +#include <hiredis/adapters/libevent.h> +#include <event2/thread.h> + +#include "rsyslog.h" +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "atomic.h" +#include "statsobj.h" +#include "unicode-helper.h" +#include "prop.h" +#include "ruleset.h" +#include "glbl.h" +#include "cfsysline.h" +#include "msg.h" +#include "dirty.h" + +MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imhiredis") + +/* static data */ +DEF_IMOD_STATIC_DATA +#define BATCH_SIZE 10 +#define WAIT_TIME_MS 500 +#define STREAM_INDEX_STR_MAXLEN 44 // "18446744073709551615-18446744073709551615" +#define IMHIREDIS_MODE_QUEUE 1 +#define IMHIREDIS_MODE_SUBSCRIBE 2 +#define IMHIREDIS_MODE_STREAM 3 +DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) +DEFobjCurrIf(glbl) +DEFobjCurrIf(statsobj) + + +typedef struct redisNode_s { + sbool isMaster; + sbool usesSocket; + uchar *socketPath; + uchar *server; + int port; + struct redisNode_s *next; +} redisNode; + + +struct instanceConf_s { + uchar *password; + uchar *key; + uchar *modeDescription; + uchar *streamConsumerGroup; + uchar *streamConsumerName; + uchar *streamReadFrom; + int streamAutoclaimIdleTime; + sbool streamConsumerACK; + int mode; + uint batchsize; + sbool useLPop; + + struct { + int nmemb; + char **name; + char **varname; + } fieldList; + + ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ + uchar *pszBindRuleset; /* default name of Ruleset to bind to */ + + redisContext *conn; + redisAsyncContext *aconn; + struct event_base *evtBase; + + redisNode *currentNode; /* currently used redis node, can be any of the nodes in the redisNodesList list */ + /* the list of seen nodes + * the preferred node (the one from configuration) will always be the first element + * second one is a master (if preferred one is unavailable/replica) or a replica, others are replicas + * the preferred node may appear twice, but it is accepted + */ + redisNode *redisNodesList; + + struct instanceConf_s *next; +}; + + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + instanceConf_t *root, *tail; +}; + +/* The following structure controls the worker threads. Global data is + * needed for their access. + */ +static struct imhiredisWrkrInfo_s { + pthread_t tid; /* the worker's thread ID */ + instanceConf_t *inst; /* Pointer to imhiredis instance */ + rsRetVal (*fnConnectMaster)(instanceConf_t *inst); + sbool (*fnIsConnected)(instanceConf_t *inst); + rsRetVal (*fnRun)(instanceConf_t *inst); +} *imhiredisWrkrInfo; + + +/* GLOBAL DATA */ +pthread_attr_t wrkrThrdAttr; /* Attribute for worker threads ; read only after startup */ + +static int activeHiredisworkers = 0; +static char *REDIS_REPLIES[] = { + "unknown", // 0 + "string", // 1 + "array", // 2 + "integer", // 3 + "nil", // 4 + "status", // 5 + "error", // 6 + "double", // 7 + "bool", // 8 + "map", // 9 + "set", // 10 + "attr", // 11 + "push", // 12 + "bignum", // 13 + "verb", // 14 + }; + +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */ + +static prop_t *pInputName = NULL; +/* there is only one global inputName for all messages generated by this input */ + + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = {}; +static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr + }; + +/* input instance parameters */ +static struct cnfparamdescr inppdescr[] = { + { "socketPath", eCmdHdlrGetWord, 0 }, + { "server", eCmdHdlrGetWord, 0 }, + { "port", eCmdHdlrInt, 0 }, + { "password", eCmdHdlrGetWord, 0 }, + { "mode", eCmdHdlrGetWord, 0 }, + { "batchsize", eCmdHdlrInt, 0 }, + { "key", eCmdHdlrGetWord, CNFPARAM_REQUIRED }, + { "uselpop", eCmdHdlrBinary, 0 }, + { "ruleset", eCmdHdlrString, 0 }, + { "stream.consumerGroup", eCmdHdlrGetWord, 0 }, + { "stream.consumerName", eCmdHdlrGetWord, 0 }, + { "stream.readFrom", eCmdHdlrGetWord, 0 }, + { "stream.consumerACK", eCmdHdlrBinary, 0 }, + { "stream.autoclaimIdleTime", eCmdHdlrNonNegInt, 0 }, + { "fields", eCmdHdlrArray, 0 }, +}; +static struct cnfparamblk inppblk = + { CNFPARAMBLK_VERSION, + sizeof(inppdescr)/sizeof(struct cnfparamdescr), + inppdescr + }; + +struct timeval glblRedisConnectTimeout = { 3, 0 }; /* 3 seconds */ + + +#include "im-helper.h" /* must be included AFTER the type definitions! */ + + +/* forward references */ +static void redisAsyncRecvCallback (redisAsyncContext __attribute__((unused)) *c, void *reply, void *inst_obj); +static void redisAsyncConnectCallback (const redisAsyncContext *c, int status); +static void redisAsyncDisconnectCallback (const redisAsyncContext *c, int status); +static struct json_object* _redisParseIntegerReply(const redisReply *reply); +static struct json_object* _redisParseStringReply(const redisReply *reply); +static struct json_object* _redisParseArrayReply(const redisReply *reply); +#ifdef REDIS_REPLY_DOUBLE +static struct json_object* _redisParseDoubleReply(const redisReply *reply); +#endif +static rsRetVal enqMsg(instanceConf_t *const inst, const char *message, size_t msgLen); +static rsRetVal enqMsgJson(instanceConf_t *const inst, struct json_object *json, struct json_object *metadata); +rsRetVal redisAuthentSynchronous(redisContext *conn, uchar *password); +rsRetVal redisAuthentAsynchronous(redisAsyncContext *aconn, uchar *password); +rsRetVal redisActualizeCurrentNode(instanceConf_t *inst); +rsRetVal redisGetServersList(redisNode *node, uchar *password, redisNode **result); +rsRetVal redisAuthenticate(instanceConf_t *inst); +rsRetVal redisConnectSync(redisContext **conn, redisNode *node); +rsRetVal connectMasterSync(instanceConf_t *inst); +static sbool isConnectedSync(instanceConf_t *inst); +rsRetVal redisConnectAsync(redisAsyncContext **aconn, redisNode *node); +rsRetVal connectMasterAsync(instanceConf_t *inst); +static sbool isConnectedAsync(instanceConf_t *inst); +rsRetVal redisDequeue(instanceConf_t *inst); +rsRetVal ensureConsumerGroupCreated(instanceConf_t *inst); +rsRetVal ackStreamIndex(instanceConf_t *inst, uchar *stream, uchar *group, uchar *index); +static rsRetVal enqueueRedisStreamReply(instanceConf_t *const inst, redisReply *reply); +static rsRetVal handleRedisXREADReply(instanceConf_t *const inst, const redisReply *reply); +static rsRetVal handleRedisXAUTOCLAIMReply( + instanceConf_t *const inst, const redisReply *reply, char **autoclaimIndex); +rsRetVal redisStreamRead(instanceConf_t *inst); +rsRetVal redisSubscribe(instanceConf_t *inst); +void workerLoop(struct imhiredisWrkrInfo_s *me); +static void *imhirediswrkr(void *myself); +static rsRetVal createRedisNode(redisNode **root); +rsRetVal copyNode(redisNode *src, redisNode **dst); +redisNode *freeNode(redisNode *node); +void insertNodeAfter(redisNode *root, redisNode *elem); +void dbgPrintNode(redisNode *node); + + +/* create input instance, set default parameters, and + * add it to the list of instances. + */ +static rsRetVal +createInstance(instanceConf_t **pinst) +{ + DEFiRet; + instanceConf_t *inst; + CHKmalloc(inst = calloc(1, sizeof(instanceConf_t))); + + inst->next = NULL; + inst->password = NULL; + inst->key = NULL; + inst->mode = 0; + inst->batchsize = 0; + inst->useLPop = 0; + inst->streamConsumerGroup = NULL; + inst->streamConsumerName = NULL; + CHKmalloc(inst->streamReadFrom = calloc(1, STREAM_INDEX_STR_MAXLEN)); + inst->streamAutoclaimIdleTime = 0; + inst->streamConsumerACK = 1; + inst->pszBindRuleset = NULL; + inst->pBindRuleset = NULL; + inst->fieldList.nmemb = 0; + + /* Redis objects */ + inst->conn = NULL; + inst->aconn = NULL; + + /* redis nodes list */ + CHKiRet(createRedisNode(&(inst->redisNodesList))); + inst->currentNode = inst->redisNodesList; + + /* libevent base for async connection */ + inst->evtBase = NULL; + + /* node created, let's add to config */ + if(loadModConf->tail == NULL) { + loadModConf->tail = loadModConf->root = inst; + } else { + loadModConf->tail->next = inst; + loadModConf->tail = inst; + } + + *pinst = inst; +finalize_it: + RETiRet; +} + +/* this function checks instance parameters and does some required pre-processing + */ +static rsRetVal ATTR_NONNULL() +checkInstance(instanceConf_t *const inst) +{ + DEFiRet; + /* first node should be created from configuration */ + assert(inst->redisNodesList != NULL); + + /* check and print redis connection settings */ + if (inst->redisNodesList->server != NULL && inst->redisNodesList->socketPath != NULL) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: both 'server' and 'socketPath' are given, " + "ignoring 'socketPath'."); + free(inst->redisNodesList->socketPath); + inst->redisNodesList->socketPath = NULL; + } + + if(inst->redisNodesList->server != NULL && inst->redisNodesList->server[0] != '\0') { + if (inst->redisNodesList->port == 0) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "imhiredis: port not set, setting default 6379"); + inst->redisNodesList->port = 6379; + } + DBGPRINTF("imhiredis: preferred server is %s (%d)\n", + inst->redisNodesList->server, + inst->redisNodesList->port); + inst->redisNodesList->usesSocket = 0; + } + else if(inst->redisNodesList->socketPath != NULL && inst->redisNodesList->socketPath[0] != '\0') { + DBGPRINTF("imhiredis: preferred server is %s\n", + inst->redisNodesList->socketPath); + inst->redisNodesList->usesSocket = 1; + } else { + LogError(0, RS_RET_CONFIG_ERROR, "imhiredis: neither 'server' nor 'socketPath' are defined!"); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + + if (inst->mode < IMHIREDIS_MODE_QUEUE || inst->mode > IMHIREDIS_MODE_STREAM) { + LogError(0, RS_RET_CONFIG_ERROR, "imhiredis: invalid mode, please choose 'subscribe', " + "'queue' or 'stream' mode."); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + if (inst->mode != IMHIREDIS_MODE_QUEUE && inst->useLPop) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: 'uselpop' set with mode != queue : ignored."); + } + + if (inst->mode == IMHIREDIS_MODE_STREAM) { + if(inst->streamConsumerGroup != NULL && inst->streamConsumerName == NULL) { + LogError(0, RS_RET_CONFIG_ERROR, "imhiredis: invalid configuration, " + "please set a consumer name when mode is 'stream' and a consumer group is set"); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + if(inst->streamAutoclaimIdleTime != 0 && inst->streamConsumerGroup == NULL) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: 'stream.autoclaimIdleTime' " + "set with no consumer group set : ignored."); + } + if(inst->streamReadFrom[0] == '\0') { + inst->streamReadFrom[0] = '$'; + } + } else { + if (inst->streamConsumerGroup != NULL) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: 'stream.consumerGroup' " + "set with mode != stream : ignored."); + } + if (inst->streamConsumerName != NULL) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: 'stream.consumerName' " + "set with mode != stream : ignored."); + } + if (inst->streamAutoclaimIdleTime != 0) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: 'stream.autoclaimIdleTime' " + "set with mode != stream : ignored."); + } + if (inst->streamConsumerACK == 0) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: 'stream.consumerACK' " + "disabled with mode != stream : ignored."); + } + if (inst->fieldList.nmemb > 0) { + LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING,"imhiredis: 'fields' " + "unused for mode != stream : ignored."); + } + } + + if (inst->batchsize !=0 ) { + DBGPRINTF("imhiredis: batchsize is '%d'\n", inst->batchsize); + } + else { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, + "imhiredis: batchsize not set, setting to default (%d)",BATCH_SIZE); + inst->batchsize=BATCH_SIZE; + } + + if (inst->password != NULL) { + DBGPRINTF("imhiredis: password is '%s'\n", inst->password); + } + + // set default current node as first node in list (preferred node) + inst->currentNode = inst->redisNodesList; + // search master node (should be either preferred node or its master) + if (RS_RET_OK != redisActualizeCurrentNode(inst) || inst->currentNode == NULL) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis: could not connect to a valid master!"); + } + +finalize_it: + RETiRet; +} + +/* function to generate an error message if the ruleset cannot be found */ +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) +{ + LogError(0, NO_ERRCODE, "imhiredis: ruleset '%s' not found - " + "using default ruleset instead", + inst->pszBindRuleset); +} + + +BEGINnewInpInst + struct cnfparamvals *pvals; + instanceConf_t *inst; + int i; +CODESTARTnewInpInst + DBGPRINTF("newInpInst (imhiredis)\n"); + + if((pvals = nvlstGetParams(lst, &inppblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("input param blk in imhiredis:\n"); + cnfparamsPrint(&inppblk, pvals); + } + + CHKiRet(createInstance(&inst)); + for(i = 0 ; i < inppblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + + if(!strcmp(inppblk.descr[i].name, "server")) { + inst->redisNodesList->server = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "socketPath")) { + inst->redisNodesList->socketPath = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "ruleset")) { + inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "port")) { + inst->redisNodesList->port = (int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "password")) { + inst->password = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "stream.consumerGroup")) { + inst->streamConsumerGroup = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "stream.consumerName")) { + inst->streamConsumerName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "stream.consumerACK")) { + inst->streamConsumerACK = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "stream.readFrom")) { + // inst->streamReadFrom is already allocated, only copy contents + memcpy(inst->streamReadFrom, + es_getBufAddr(pvals[i].val.d.estr), + es_strlen(pvals[i].val.d.estr)); + inst->streamReadFrom[es_strlen(pvals[i].val.d.estr)] = '\0'; + } else if(!strcmp(inppblk.descr[i].name, "stream.autoclaimIdleTime")) { + inst->streamAutoclaimIdleTime = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "uselpop")) { + inst->useLPop = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "mode")) { + inst->modeDescription = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + if (!strcmp((const char*)inst->modeDescription, "queue")) { + inst->mode = IMHIREDIS_MODE_QUEUE; + } else if (!strcmp((const char*)inst->modeDescription, "subscribe")) { + inst->mode = IMHIREDIS_MODE_SUBSCRIBE; + } else if (!strcmp((const char*)inst->modeDescription, "stream")) { + inst->mode = IMHIREDIS_MODE_STREAM; + } else { + LogMsg(0, RS_RET_PARAM_ERROR, LOG_ERR, "imhiredis: unsupported mode " + "'%s'", inst->modeDescription); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + } else if (!strcmp(inppblk.descr[i].name, "fields")) { + inst->fieldList.nmemb = pvals[i].val.d.ar->nmemb; + CHKmalloc(inst->fieldList.name = calloc(inst->fieldList.nmemb, sizeof(char *))); + CHKmalloc(inst->fieldList.varname = calloc(inst->fieldList.nmemb, sizeof(char *))); + for (int j = 0; j < pvals[i].val.d.ar->nmemb; ++j) { + char *const param = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); + char *varname = NULL; + char *name; + if(*param == ':') { + char *b = strchr(param+1, ':'); + if(b == NULL) { + LogMsg(0, RS_RET_PARAM_ERROR, LOG_ERR, + "imhiredis: missing closing colon: '%s'", param); + ABORT_FINALIZE(RS_RET_ERR); + } + *b = '\0'; /* split name & varname */ + varname = param+1; + name = b+1; + } else { + name = param; + } + CHKmalloc(inst->fieldList.name[j] = strdup(name)); + char vnamebuf[1024]; + snprintf(vnamebuf, sizeof(vnamebuf), + "!%s", (varname == NULL) ? name : varname); + CHKmalloc(inst->fieldList.varname[j] = strdup(vnamebuf)); + DBGPRINTF("will map '%s' to '%s'\n", + inst->fieldList.name[j], + inst->fieldList.varname[j]); + free(param); + } + } else if(!strcmp(inppblk.descr[i].name, "batchsize")) { + inst->batchsize = (int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "key")) { + inst->key = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else { + dbgprintf("imhiredis: program error, non-handled " + "param '%s'\n", inppblk.descr[i].name); + } + } + + DBGPRINTF("imhiredis: checking config sanity\n"); + if (inst->modeDescription == NULL) { + CHKmalloc(inst->modeDescription = (uchar*)strdup("subscribe")); + inst->mode = IMHIREDIS_MODE_SUBSCRIBE; + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "imhiredis: \"mode\" parameter not specified " + "using default redis 'subscribe' mode -- this may not be what you want!"); + } + if (inst->key == NULL) { + LogMsg(0, RS_RET_PARAM_ERROR, LOG_ERR, "imhiredis: \"key\" required parameter not specified!"); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + if(inst->redisNodesList->server == NULL && inst->redisNodesList->socketPath == NULL) { + CHKmalloc(inst->redisNodesList->server = (uchar *)strdup("127.0.0.1")); + inst->redisNodesList->port = 6379; + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "imhiredis: no server parameter specified " + "using default 127.0.0.1:6379 -- this may not be what you want!"); + } + if (inst->password == NULL) { + LogMsg(0, RS_RET_OK, LOG_INFO, "imhiredis: no password specified"); + } + + DBGPRINTF("imhiredis: newInpInst key=%s, mode=%s, uselpop=%d\n", + inst->key, inst->modeDescription, inst->useLPop); + +finalize_it: +CODE_STD_FINALIZERnewInpInst + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "imhiredis: error processing module " + "config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for imhiredis:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) { + continue; + } else { + dbgprintf("imhiredis: program error, non-handled " + "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); + } + } +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf + instanceConf_t *inst; +CODESTARTcheckCnf + for(inst = pModConf->root ; inst != NULL ; inst = inst->next) { + std_checkRuleset(pModConf, inst); + } +ENDcheckCnf + + +BEGINactivateCnfPrePrivDrop +CODESTARTactivateCnfPrePrivDrop + runModConf = pModConf; +ENDactivateCnfPrePrivDrop + +BEGINactivateCnf +CODESTARTactivateCnf + for(instanceConf_t *inst = pModConf->root ; inst != NULL ; inst = inst->next) { + iRet = checkInstance(inst); + if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE) + inst->evtBase = event_base_new(); + } +ENDactivateCnf + + +BEGINfreeCnf + instanceConf_t *inst, *del; + redisNode *node; +CODESTARTfreeCnf + for(inst = pModConf->root ; inst != NULL ; ) { + if (inst->evtBase) + event_base_free(inst->evtBase); + if (inst->password != NULL) + free(inst->password); + free(inst->modeDescription); + free(inst->key); + if(inst->streamConsumerGroup != NULL) + free(inst->streamConsumerGroup); + if(inst->streamConsumerName != NULL) + free(inst->streamConsumerName); + free(inst->streamReadFrom); + free(inst->pszBindRuleset); + if(inst->fieldList.name != NULL) { + for(int i = 0 ; i < inst->fieldList.nmemb ; ++i) { + free(inst->fieldList.name[i]); + free(inst->fieldList.varname[i]); + } + free(inst->fieldList.name); + free(inst->fieldList.varname); + } + if(inst->conn != NULL) { + redisFree(inst->conn); + inst->conn = NULL; + } + if(inst->aconn != NULL) { + redisAsyncFree(inst->aconn); + inst->aconn = NULL; + } + + for (node = inst->redisNodesList; node != NULL; node = freeNode(node)) {;} + + del = inst; + inst = inst->next; + free(del); + } +ENDfreeCnf + + +/* Cleanup imhiredis worker threads */ +static void +shutdownImhiredisWorkers(void) +{ + int i; + instanceConf_t *inst; + + assert(imhiredisWrkrInfo != NULL); + + for(inst = runModConf->root ; inst != NULL ; inst = inst->next) { + if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE && inst->aconn) { + DBGPRINTF("imhiredis: disconnecting async worker\n"); + redisAsyncDisconnect(inst->aconn); + } + } + + // event_base_loopbreak(runModConf->evtBase); + + DBGPRINTF("imhiredis: waiting on imhiredis workerthread termination\n"); + for(i = 0 ; i < activeHiredisworkers ; ++i) { + pthread_join(imhiredisWrkrInfo[i].tid, NULL); + DBGPRINTF("imhiredis: Stopped worker %d\n", i); + } + free(imhiredisWrkrInfo); + imhiredisWrkrInfo = NULL; + + return; +} + + +/* This function is called to gather input. */ +BEGINrunInput + int i; + instanceConf_t *inst; +CODESTARTrunInput + DBGPRINTF("imhiredis: runInput loop started ...\n"); + activeHiredisworkers = 0; + for(inst = runModConf->root ; inst != NULL ; inst = inst->next) { + ++activeHiredisworkers; + } + + if(activeHiredisworkers == 0) { + LogError(0, RS_RET_ERR, "imhiredis: no active inputs, input does " + "not run - there should have been additional error " + "messages given previously"); + ABORT_FINALIZE(RS_RET_ERR); + } + + + DBGPRINTF("imhiredis: Starting %d imhiredis workerthreads\n", activeHiredisworkers); + imhiredisWrkrInfo = calloc(activeHiredisworkers, sizeof(struct imhiredisWrkrInfo_s)); + if (imhiredisWrkrInfo == NULL) { + LogError(errno, RS_RET_OUT_OF_MEMORY, "imhiredis: worker-info array allocation failed."); + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + + /* Start worker threads for each imhiredis input source + */ + i = 0; + for(inst = runModConf->root ; inst != NULL ; inst = inst->next) { + /* init worker info structure! */ + imhiredisWrkrInfo[i].inst = inst; /* Set reference pointer */ + pthread_create(&imhiredisWrkrInfo[i].tid, &wrkrThrdAttr, imhirediswrkr, &(imhiredisWrkrInfo[i])); + i++; + } + + // This thread simply runs the various threads, then waits for Rsyslog to stop + while(glbl.GetGlobalInputTermState() == 0) { + if(glbl.GetGlobalInputTermState() == 0) + /* Check termination state every 0.5s + * should be sufficient to grant fast response to shutdown while not hogging CPU + */ + srSleep(0, 500000); + } + DBGPRINTF("imhiredis: terminating upon request of rsyslog core\n"); + + shutdownImhiredisWorkers(); +finalize_it: +ENDrunInput + + +BEGINwillRun +CODESTARTwillRun + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imhiredis"), sizeof("imhiredis") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); +finalize_it: +ENDwillRun + + +BEGINafterRun +CODESTARTafterRun + if(pInputName != NULL) + prop.Destruct(&pInputName); + +ENDafterRun + + +BEGINmodExit +CODESTARTmodExit + pthread_attr_destroy(&wrkrThrdAttr); + + /* force cleaning of all libevent-related structures + * (clean shutdowns are not always guaranteed without it) + */ + libevent_global_shutdown(); + + /* release objects we used */ + objRelease(statsobj, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); +ENDmodExit + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURENonCancelInputTermination) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES +CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; +CODEmodInit_QueryRegCFSLineHdlr + /* request objects we use */ + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); + + /* initialize "read-only" thread attributes */ + pthread_attr_init(&wrkrThrdAttr); + pthread_attr_setstacksize(&wrkrThrdAttr, 4096*1024); + + /* activate libevent for (p)threads support */ + evthread_use_pthreads(); + +ENDmodInit + + +/* ------------------------------ callbacks ------------------------------ */ + + +/** + * Asynchronous subscribe callback handler + */ +static void redisAsyncRecvCallback (redisAsyncContext *aconn, void *reply, void __attribute__((unused)) *unused) { + /* + redisReply is supposed to be an array of three elements: [''message', <channel>, <message>] + + + JJO: For future reference (https://github.com/redis/hiredis/blob/master/README.md) + + Important: the current version of hiredis (1.0.0) frees replies when the asynchronous API is used. + This means you should not call freeReplyObject when you use this API. + The reply is cleaned up by hiredis after the callback returns. + TODO We may have to change this function in the future to free replies. + */ + instanceConf_t *const inst = (instanceConf_t *) aconn->data; + redisReply * r = (redisReply *) reply; + if (r == NULL) return; + + if (r->elements < 3 || r->element[2]->str == NULL) { + return; + } + enqMsg(inst, r->element[2]->str, r->element[2]->len); + + return; +} + + +/** + * Asynchronous connection callback handler + */ +static void redisAsyncConnectCallback (const redisAsyncContext *c, int status) { + if (status != REDIS_OK) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "imhiredis (async): could not connect to redis: " + "%s", c->errstr); + // remove async context from instance config object, still contained in context's 'data' field + instanceConf_t *inst = (instanceConf_t *) c->data; + assert(inst != NULL); + inst->aconn = NULL; + return; + } + DBGPRINTF("imhiredis (async): successfully connected!\n"); + + return; +} + + +/** + * Asynchronous disconnection callback handler + */ +static void redisAsyncDisconnectCallback (const redisAsyncContext *c, int status) { + + // remove context from instance config object (which is stored in the context 'data' field by us) + // context will be freed by the library, so it's only set to NULL here + instanceConf_t *inst = (instanceConf_t *) c->data; + assert(inst != NULL); + inst->aconn = NULL; + inst->currentNode = NULL; + + if (status != REDIS_OK) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "imhiredis (async): got disconnected from redis: " + "%s", c->errstr); + return; + } + DBGPRINTF("imhiredis (async): successfully disconnected!\n"); + + return; +} + + +/* ------------------------------ end callbacks ------------------------------ */ + +/* + * sends a ROLE command to the redis pointed by context + * context should be a valid redis context + * returns a valid redisReply pointer if an array reply was received, NULL otherwise + */ +redisReply *getRole(redisContext *c) { + redisReply *reply; + + assert(c != NULL); + + reply = redisCommand(c, "ROLE"); + if (reply == NULL) { + DBGPRINTF("imhiredis: could not get reply from ROLE command\n"); + } + else if (reply->type == REDIS_REPLY_ERROR) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis got an error while querying role -> " + "%s\n", reply->str); + freeReplyObject(reply); + reply = NULL; + } + else if (reply->type != REDIS_REPLY_ARRAY) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "imhiredis: did not get an array from ROLE command"); + freeReplyObject(reply); + reply = NULL; + } + + return reply; +} + + +static struct json_object* _redisParseIntegerReply(const redisReply *reply) { + return json_object_new_int64(reply->integer); +} + +#ifdef REDIS_REPLY_DOUBLE +static struct json_object* _redisParseDoubleReply(const redisReply *reply) { + return json_object_new_double_s(reply->dval, reply->str); +} +#endif + +static struct json_object* _redisParseStringReply(const redisReply *reply) { + return json_object_new_string_len(reply->str, reply->len); +} + +static struct json_object* _redisParseArrayReply(const redisReply *reply) { + struct json_object *result = NULL; + struct json_object *res = NULL; + char *key = NULL; + + result = json_object_new_object(); // the redis type name is ARRAY, but represents a dict + + if (result != NULL) { + for(size_t i = 0; i < reply->elements; i++) { + if (reply->element[i]->type == REDIS_REPLY_STRING && i % 2 == 0) { + key = reply->element[i]->str; + } else { + switch(reply->element[i]->type) { + case REDIS_REPLY_INTEGER: + res = _redisParseIntegerReply(reply->element[i]); + json_object_object_add(result, key, res); + break; +#ifdef REDIS_REPLY_DOUBLE + case REDIS_REPLY_DOUBLE: + res = _redisParseDoubleReply(reply->element[i]); + json_object_object_add(result, key, res); + break; +#endif + case REDIS_REPLY_STRING: + res = _redisParseStringReply(reply->element[i]); + json_object_object_add(result, key, res); + break; + case REDIS_REPLY_ARRAY: + res = _redisParseArrayReply(reply->element[i]); + json_object_object_add(result, key, res); + break; + default: + DBGPRINTF("Unhandled case!\n"); + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, + "Redis reply object contains an unhandled type!"); + break; + } + } + } + } + + return result; +} + + +/* + * enqueue the hiredis message. The provided string is + * not freed - this must be done by the caller. + */ +static rsRetVal enqMsg(instanceConf_t *const inst, const char *message, size_t msgLen) { + DEFiRet; + smsg_t *pMsg; + + if (message == NULL || message[0] == '\0') { + /* we do not process empty lines */ + FINALIZE; + } + + DBGPRINTF("imhiredis: enqMsg: Msg -> '%s'\n", message); + + CHKiRet(msgConstruct(&pMsg)); + MsgSetInputName(pMsg, pInputName); + MsgSetRawMsg(pMsg, message, msgLen); + MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); + MsgSetRuleset(pMsg, inst->pBindRuleset); + MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ + CHKiRet(submitMsg2(pMsg)); + +finalize_it: + RETiRet; +} + + +static rsRetVal enqMsgJson(instanceConf_t *const inst, struct json_object *json, struct json_object *metadata) { + DEFiRet; + smsg_t *pMsg; + struct json_object *tempJson = NULL; + + assert(json != NULL); + + CHKiRet(msgConstruct(&pMsg)); // In case of allocation error -> needs to break + MsgSetInputName(pMsg, pInputName); + MsgSetRuleset(pMsg, inst->pBindRuleset); + MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ + if(RS_RET_OK != MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY)) + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, + "Could not set Flow Control on message."); + if(inst->fieldList.nmemb != 0) { + for (int i = 0; i < inst->fieldList.nmemb; i++) + { + DBGPRINTF("processing field '%s'\n", inst->fieldList.name[i]); + + /* case 1: static field. We simply forward it */ + if (inst->fieldList.name[i][0] != '!' && inst->fieldList.name[i][0] != '.') + { + DBGPRINTF("field is static, taking it as it is...\n"); + tempJson = json_object_new_string(inst->fieldList.name[i]); + } + /* case 2: dynamic field. We retrieve its value from the JSON logline and add it */ + else + { + DBGPRINTF("field is dynamic, searching in root object...\n"); + if (!json_object_object_get_ex(json, inst->fieldList.name[i]+1, &tempJson)) { + + DBGPRINTF("Did not find value %s in message\n", inst->fieldList.name[i]); + continue; + } + // Getting object as it will not keep the same lifetime as its origin object + tempJson = json_object_get(tempJson); + // original object is put: no need for it anymore + json_object_put(json); + } + + DBGPRINTF("got value of field '%s'\n", inst->fieldList.name[i]); + DBGPRINTF("will insert to '%s'\n", inst->fieldList.varname[i]); + + if(RS_RET_OK != msgAddJSON(pMsg, (uchar *)inst->fieldList.varname[i], tempJson, 0, 0)) { + LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, + "Failed to add value to '%s'", inst->fieldList.varname[i]); + } + + tempJson = NULL; + } + } else { + if(RS_RET_OK != msgAddJSON(pMsg, (uchar*)"!", json, 0, 0)) { + LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, + "Failed to add json info to message!"); + ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); + } + } + if (metadata != NULL && RS_RET_OK != msgAddJSON(pMsg, (uchar*)".", metadata, 0, 0)) { + LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, + "Failed to add metadata to message!"); + ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); + } + if(RS_RET_OK != submitMsg2(pMsg)) { + LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, + "Failed to submit message to main queue!"); + ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); + } + DBGPRINTF("enqMsgJson: message enqueued!\n"); + +finalize_it: + RETiRet; +} + + +/* + * execute a synchronous authentication using the context conn + * conn and password should be non-NULL + * conn should be a valid context + */ +rsRetVal redisAuthentSynchronous(redisContext *conn, uchar *password) { + DEFiRet; + redisReply *reply = NULL; + + assert(conn != NULL); + assert(password != NULL); + assert(password[0] != '\0'); + + reply = (redisReply *) redisCommand(conn, "AUTH %s", password); + if (reply == NULL) { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis: Could not authenticate!\n"); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } else if (strncmp(reply->str, "OK", 2)) { + LogError(0, RS_RET_REDIS_AUTH_FAILED, "imhiredis: Authentication failure -> %s\n", reply->str); + ABORT_FINALIZE(RS_RET_REDIS_AUTH_FAILED); + } + +finalize_it: + if(reply) + freeReplyObject(reply); + RETiRet; +} + + +/* + * execute an asynchronous authentication using the context aconn + * aconn and password should be non-NULL + * aconn should be a valid (async) context + */ +rsRetVal redisAuthentAsynchronous(redisAsyncContext *aconn, uchar *password) { + DEFiRet; + + assert(aconn != NULL); + assert(password != NULL); + assert(password[0] != '\0'); + + if (REDIS_OK != redisAsyncCommand(aconn, NULL, NULL, "AUTH %s", password)) { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis: error while authenticating asynchronously -> %s\n", + aconn->errstr); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + +finalize_it: + RETiRet; +} + + +/* + * connect to node, authenticate (if necessary), get role, then get all node information provided by ROLE + * node should be a non-NULL valid redisNode pointer + * password can be NULL, meaning no authentication will be done + * result will hold the result of the ROLE command executed on the node: + * - NULL if the node was a single master instance + * - a single (master) node if the provided node was a replica + * - a list of (replica) nodes if the provided node was a master + */ +rsRetVal redisGetServersList(redisNode *node, uchar *password, redisNode **result) { + DEFiRet; + redisContext *context; + redisReply *reply = NULL, *replica; + unsigned int i; + + assert(node != NULL); + + CHKiRet(redisConnectSync(&context, node)); + + if(password != NULL && password[0] != '\0') { + CHKiRet(redisAuthentSynchronous(context, password)); + } + + reply = getRole(context); + + if(reply == NULL) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis: did not get the role of the server"); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + + /* + * string comparisons for ROLE could be skipped + * as each role returns a different number of elements, + * but lets keep it as a security... + */ + if ( reply->elements == 5 && + strncmp(reply->element[0]->str, "slave", 5) == 0) { + + CHKiRet(createRedisNode(result)); + (*result)->server = (uchar *) strdup((const char *)reply->element[1]->str); + (*result)->port = reply->element[2]->integer; + (*result)->isMaster = 1; + } + else if ( reply->elements == 3 && + reply->element[2]->type == REDIS_REPLY_ARRAY && + strncmp(reply->element[0]->str, "master", 6) == 0) { + + // iterate on all replicas given in the reply (if any) + for (i = 0; i < reply->element[2]->elements; i++) { + replica = reply->element[2]->element[i]; + + if (replica->type == REDIS_REPLY_ARRAY && replica->elements == 3) { + /* node will be a new node every time + * with old ones shifted in the list + */ + CHKiRet(createRedisNode(result)); + (*result)->server = (uchar *) strdup((const char *)replica->element[0]->str); + // yes, the value in that case is a string and NOT an integer! + (*result)->port = atoi(replica->element[1]->str); + } + } + } else { + // we have a sentinel, or a problem + ABORT_FINALIZE(RS_RET_NOT_FOUND); + } + +finalize_it: + if (reply != NULL) + freeReplyObject(reply); + if (context != NULL) + redisFree(context); + RETiRet; +} + + + +/* + * actualize the current master node to use during connection for instance inst + * inst should be a valid, non-NULL instanceConf object + * inst should also possess at least a single node in inst->redisNodeList + * if the function returns RS_RET_OK, inst->currentNode and inst->redisNodeList have been both updated + * to reflect new master and potential replicas + * the first configured node (called preferred node) is always kept as the first entry in redisNodeList + */ +rsRetVal redisActualizeCurrentNode(instanceConf_t *inst) { + DEFiRet; + redisReply *reply = NULL; + redisNode *node, *tmp, *newList = NULL; + + assert(inst != NULL); + assert(inst->redisNodesList != NULL); + + inst->currentNode = NULL; + // keep first node in list = preferred node (comes from configuration) + copyNode(inst->redisNodesList, &newList); + newList->next = NULL; + + for (node = inst->redisNodesList; node != NULL; node = node->next) { + tmp = NULL; + + DBGPRINTF("imhiredis: trying to connect to node to get info...\n"); + dbgPrintNode(node); + + if (RS_RET_OK == redisGetServersList(node, inst->password, &tmp)) { + // server replied + + if (tmp && tmp->isMaster) { + DBGPRINTF("imhiredis: node replied with a master node, is a replica\n"); + // master node, keep it as potential new active node + inst->currentNode = tmp; + tmp = NULL; + + // try to connect to the master and get replicas + if(RS_RET_OK != redisGetServersList(inst->currentNode, inst->password, &tmp)) { + + /* had a master, but cannot connect + * save suspected master in new list but keep searching with other nodes + */ + DBGPRINTF("imhiredis: had a master but cannot connect, keeping in list\n"); + dbgPrintNode(inst->currentNode); + insertNodeAfter(newList, inst->currentNode); + inst->currentNode = NULL; + continue; + } + } else { + DBGPRINTF("imhiredis: node replied with a list of replicas, is a master\n"); + // copy the node to the new currentNode, list owning node will be freed + node->isMaster = 1; + copyNode(node, &(inst->currentNode)); + inst->currentNode->next = NULL; + } + + /* + * here, tmp is a list of replicas or NULL (single node) + * inst->currentNode is the new active master + */ + + // add the replicas to the list + if (tmp) { + insertNodeAfter(newList, tmp); + DBGPRINTF("imhiredis: inserting replicas to list\n"); + for (tmp = newList->next; tmp != NULL; tmp = tmp->next) { + dbgPrintNode(tmp); + } + } + // insert the master after the preferred node (configuration) + DBGPRINTF("imhiredis: inserting new master node in list\n"); + dbgPrintNode(inst->currentNode); + insertNodeAfter(newList, inst->currentNode); + + // swap newList and redisNodesList to free old list at the end of the function + tmp = newList; + newList = inst->redisNodesList; + inst->redisNodesList = tmp; + FINALIZE; + } + } + + DBGPRINTF("imhiredis: did not find a valid master"); + iRet = RS_RET_NOT_FOUND; + inst->currentNode = NULL; + +finalize_it: + if (reply != NULL) + freeReplyObject(reply); + // newList is always completely freed + for (node = newList; node != NULL; ) { + node = freeNode(node); + } + + RETiRet; +} + + +/* + * authentication function, for both synchronous and asynchronous modes (queue or subscribe) + * inst, inst->curentMode and inst->password should not be NULL + */ +rsRetVal redisAuthenticate(instanceConf_t *inst) { + DEFiRet; + redisContext *usedContext = NULL; + redisReply *reply = NULL; + + assert(inst != NULL); + assert(inst->currentNode != NULL); + assert(inst->password != NULL); + assert(inst->password[0] != '\0'); + + DBGPRINTF("imhiredis: authenticating...\n"); + + // Create a temporary context for synchronous connection, used to validate AUTH command in asynchronous contexts + if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE) { + if (RS_RET_OK != redisConnectSync(&usedContext, inst->currentNode)) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis: could not connect to current " + "active node synchronously to validate authentication"); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + } else { + usedContext = inst->conn; + } + + /* + * Try synchronous connection, whatever the method for the instance + * This is also done for the asynchronous mode, to validate the successful authentication + */ + CHKiRet(redisAuthentSynchronous(usedContext, inst->password)); + + if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE) { + CHKiRet(redisAuthentAsynchronous(inst->aconn, inst->password)); + } + + DBGPRINTF("imhiredis: authentication successful\n"); + +finalize_it: + if(inst->mode == IMHIREDIS_MODE_SUBSCRIBE && usedContext) + redisFree(usedContext); + if(reply) + freeReplyObject(reply); + RETiRet; +} + + +/* + * connection function for synchronous (queue) mode + * node should not be NULL + */ +rsRetVal redisConnectSync(redisContext **conn, redisNode *node) { + DEFiRet; + + assert(node != NULL); + + if (node->usesSocket) + *conn = redisConnectUnixWithTimeout((const char *)node->socketPath, glblRedisConnectTimeout); + else + *conn = redisConnectWithTimeout((const char *)node->server, node->port, glblRedisConnectTimeout); + + if (*conn == NULL) { + if (node->usesSocket) { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s' " + "-> could not allocate context!\n", node->socketPath); + } else { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s', " + "port %d -> could not allocate context!\n", node->server, node->port); + } + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + else if ((*conn)->err) { + if (node->usesSocket) { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s' " + "-> %s\n", node->socketPath, (*conn)->errstr); + } else { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s', " + "port %d -> %s\n", node->server, node->port, (*conn)->errstr); + } + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + +finalize_it: + if (iRet != RS_RET_OK) { + if (*conn) + redisFree(*conn); + *conn = NULL; + } + RETiRet; +} + + +/* + * connection function for asynchronous (subscribe) mode + * node should not be NULL + */ +rsRetVal redisConnectAsync(redisAsyncContext **aconn, redisNode *node) { + DEFiRet; + + assert(node != NULL); + + if (node->usesSocket) + *aconn = redisAsyncConnectUnix((const char*)node->socketPath); + else + *aconn = redisAsyncConnect((const char *)node->server, node->port); + + if(*aconn == NULL) { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis (async): could not allocate context!\n"); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } else if ((*aconn)->err) { + if (node->usesSocket) { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis (async): cannot connect to server '%s' " + "-> %s\n", node->socketPath, (*aconn)->errstr); + } else { + LogError(0, RS_RET_REDIS_ERROR, "imhiredis (async): cannot connect to server '%s', port '%d' " + "-> %s\n", node->server, node->port, (*aconn)->errstr); + } + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + +finalize_it: + if (iRet != RS_RET_OK) { + if(*aconn) + redisAsyncFree(*aconn); + *aconn = NULL; + } + RETiRet; +} + +/* + * Helper method to connect to the current master asynchronously + * 'inst' parameter should be non-NULL and have a valid currentNode object + */ +rsRetVal connectMasterAsync(instanceConf_t *inst) { + DEFiRet; + + if(RS_RET_OK != redisConnectAsync(&(inst->aconn), inst->currentNode)) { + inst->currentNode = NULL; + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + if( inst->password != NULL && + inst->password[0] != '\0' && + RS_RET_OK != redisAuthenticate(inst)) { + + redisAsyncFree(inst->aconn); + inst->aconn = NULL; + inst->currentNode = NULL; + ABORT_FINALIZE(RS_RET_REDIS_AUTH_FAILED); + } + + // finalize context creation + inst->aconn->data = (void *)inst; + redisAsyncSetConnectCallback(inst->aconn, redisAsyncConnectCallback); + redisAsyncSetDisconnectCallback(inst->aconn, redisAsyncDisconnectCallback); + redisLibeventAttach(inst->aconn, inst->evtBase); + +finalize_it: + RETiRet; +} + + +/* + * Helper method to check if (async) instance is connected + */ +static sbool isConnectedAsync(instanceConf_t *inst) { + return inst->aconn != NULL; +} + + +/* + * Helper method to connect to the current master synchronously + * 'inst' parameter should be non-NULL and have a valid currentNode object + */ +rsRetVal connectMasterSync(instanceConf_t *inst) { + DEFiRet; + + if(RS_RET_OK != redisConnectSync(&(inst->conn), inst->currentNode)) { + inst->currentNode = NULL; + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + if( inst->password != NULL && + inst->password[0] != '\0' && + RS_RET_OK != redisAuthenticate(inst)) { + + redisFree(inst->conn); + inst->conn = NULL; + inst->currentNode = NULL; + ABORT_FINALIZE(RS_RET_REDIS_AUTH_FAILED); + } + +finalize_it: + RETiRet; +} + + +/* + * Helper method to check if instance is connected + */ +static sbool isConnectedSync(instanceConf_t *inst) { + return inst->conn != NULL; +} + +/* + * dequeue all entries in the redis list, using batches of 10 commands + */ +rsRetVal redisDequeue(instanceConf_t *inst) { + DEFiRet; + redisReply *reply = NULL; + uint replyType = 0, i; + + assert(inst != NULL); + + DBGPRINTF("redisDequeue: beginning to dequeue key '%s'\n", inst->key); + + do { + // append a batch of inst->batchsize POP commands (either LPOP or RPOP depending on conf) + if (inst->useLPop == 1) { + DBGPRINTF("redisDequeue: Queuing #%d LPOP commands on key '%s' \n", + inst->batchsize, + inst->key); + for (i=0; i<inst->batchsize; ++i ) { + if (REDIS_OK != redisAppendCommand(inst->conn, "LPOP %s", inst->key)) + break; + } + } else { + DBGPRINTF("redisDequeue: Queuing #%d RPOP commands on key '%s' \n", + inst->batchsize, + inst->key); + for (i=0; i<inst->batchsize; i++) { + if (REDIS_OK != redisAppendCommand(inst->conn, "RPOP %s", inst->key)) + break; + } + } + + DBGPRINTF("redisDequeue: Dequeuing...\n") + // parse responses from appended commands + do { + if (REDIS_OK != redisGetReply(inst->conn, (void **) &reply)) { + // error getting reply, must stop + LogError(0, RS_RET_REDIS_ERROR, "redisDequeue: Error reading reply after POP #%d " + "on key '%s'", (inst->batchsize - i), inst->key); + // close connection + redisFree(inst->conn); + inst->currentNode = NULL; + inst->conn = NULL; + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } else { + if (reply != NULL) { + replyType = reply->type; + switch(replyType) { + case REDIS_REPLY_STRING: + enqMsg(inst, reply->str, reply->len); + break; + case REDIS_REPLY_NIL: + // replies are dequeued but are empty = end of list + break; + case REDIS_REPLY_ERROR: + // There is a problem with the key or the Redis instance + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisDequeue: error " + "while POP'ing key '%s' -> %s", inst->key, reply->str); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + default: + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "redisDequeue: " + "unexpected reply type: %s", REDIS_REPLIES[replyType%15]); + } + freeReplyObject(reply); + reply = NULL; + } else { /* reply == NULL */ + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisDequeue: unexpected empty reply " + "for successful return"); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + } + + // while there are replies to unpack, continue + } while (--i > 0); + + if(replyType == REDIS_REPLY_NIL) { + /* sleep 1s between 2 POP tries, when no new entries are available (list is empty) + * this does NOT limit dequeing rate, but prevents the input from polling Redis too often + */ + for(i = 0; i < 10; i++) { + // Time to stop the thread + if (glbl.GetGlobalInputTermState() != 0) + FINALIZE; + // 100ms sleeps + srSleep(0, 100000); + } + } + + // while input can run, continue with a new batch + } while (glbl.GetGlobalInputTermState() == 0); + + DBGPRINTF("redisDequeue: finished to dequeue key '%s'\n", inst->key); + +finalize_it: + if (reply) + freeReplyObject(reply); + RETiRet; +} + + +rsRetVal ensureConsumerGroupCreated(instanceConf_t *inst) { + DEFiRet; + redisReply *reply = NULL; + + DBGPRINTF("ensureConsumerGroupCreated: Creating group %s on stream %s\n", inst->streamConsumerGroup, inst->key); + + reply = (redisReply *)redisCommand(inst->conn, "XGROUP CREATE %s %s %s MKSTREAM", + inst->key, + inst->streamConsumerGroup, + inst->streamReadFrom); + if(reply != NULL) { + switch(reply->type) { + case REDIS_REPLY_STATUS: + case REDIS_REPLY_STRING: + if(0 == strncmp("OK", reply->str, reply->len)) + DBGPRINTF("ensureConsumerGroupCreated: Consumer group %s created successfully " + "for stream %s\n", + inst->streamConsumerGroup, + inst->key); + break; + case REDIS_REPLY_ERROR: + if(strcasestr(reply->str, "BUSYGROUP") != NULL) { + DBGPRINTF("ensureConsumerGroupCreated: Consumer group %s already exists for " + "stream %s, ignoring\n", + inst->streamConsumerGroup, + inst->key); + } else { + LogError(0, RS_RET_ERR, "ensureConsumerGroupCreated: An unknown error " + "occurred while creating a Consumer group %s on stream %s -> %s", + inst->streamConsumerGroup, + inst->key, + reply->str); + ABORT_FINALIZE(RS_RET_ERR); + } + break; + default: + LogError(0, RS_RET_ERR, "ensureConsumerGroupCreated: An unknown reply was received " + "-> %s", REDIS_REPLIES[(reply->type)%15]); + ABORT_FINALIZE(RS_RET_ERR); + } + } else { + LogError(0, RS_RET_REDIS_ERROR, "ensureConsumerGroupCreated: Could not create group %s on stream %s!", + inst->streamConsumerGroup, + inst->key); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + +finalize_it: + if(reply != NULL) + freeReplyObject(reply); + RETiRet; +} + + +rsRetVal ackStreamIndex(instanceConf_t *inst, uchar *stream, uchar *group, uchar *index) { + DEFiRet; + redisReply *reply = NULL; + + DBGPRINTF("ackStream: Acknowledging index '%s' in stream %s\n", index, stream); + + reply = (redisReply *)redisCommand(inst->conn, "XACK %s %s %s", + stream, + group, + index); + if(reply != NULL) { + switch(reply->type) { + case REDIS_REPLY_INTEGER: + if(reply->integer == 1) { + DBGPRINTF("ackStreamIndex: index successfully acknowledged " + "for stream %s\n", + inst->key); + } else { + DBGPRINTF("ackStreamIndex: message was not acknowledged " + "-> already done?"); + } + break; + case REDIS_REPLY_ERROR: + LogError(0, RS_RET_ERR, "ackStreamIndex: An error occurred " + "while trying to ACK message %s on %s[%s] -> %s", + index, + stream, + group, + reply->str); + ABORT_FINALIZE(RS_RET_ERR); + default: + LogError(0, RS_RET_ERR, "ackStreamIndex: unexpected reply type: %s", + REDIS_REPLIES[(reply->type)%15]); + ABORT_FINALIZE(RS_RET_ERR); + } + + } else { + LogError(0, RS_RET_REDIS_ERROR, "ackStreamIndex: Could not ACK message with index %s for %s[%s]!", + index, + stream, + group); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + +finalize_it: + if(reply != NULL) { + freeReplyObject(reply); + } + RETiRet; +} + + +static rsRetVal enqueueRedisStreamReply(instanceConf_t *const inst, redisReply *reply) { + DEFiRet; + struct json_object *json = NULL, *metadata = NULL, *redis = NULL; + + json = _redisParseArrayReply(reply->element[1]); + + CHKmalloc(metadata = json_object_new_object()); + CHKmalloc(redis = json_object_new_object()); + json_object_object_add(redis, "stream", json_object_new_string((char *)inst->key)); + json_object_object_add(redis, "index", _redisParseStringReply(reply->element[0])); + if(inst->streamConsumerGroup != NULL) { + json_object_object_add(redis, "group", json_object_new_string((char *)inst->streamConsumerGroup)); + } + if(inst->streamConsumerName != NULL) { + json_object_object_add(redis, "consumer", json_object_new_string((char *)inst->streamConsumerName)); + } + + // ownership of redis object allocated by json_object_new_object() is taken by json + // no need to free/destroy/put redis object + json_object_object_add(metadata, "redis", redis); + + CHKiRet(enqMsgJson(inst, json, metadata)); + // enqueued message successfully, json and metadata objects are now owned by enqueued message + // no need to free/destroy/put json objects + json = NULL; + metadata = NULL; + + if(inst->streamConsumerGroup != NULL && inst->streamConsumerACK) { + CHKiRet(ackStreamIndex( + inst, + (uchar *)inst->key, + inst->streamConsumerGroup, + (uchar *)reply->element[0]->str + )); + } + +finalize_it: + // If that happens, there was an error during one of the steps and the json object is not enqueued + if(json != NULL) json_object_put(json); + if(metadata != NULL) json_object_put(metadata); + RETiRet; +} + + +/* + * handle the hiredis Stream XREAD/XREADGROUP return objects. The provided reply is + * not freed - this must be done by the caller. + * example of stream to parse: + * 1) 1) "mystream" <- name of the stream indexes are from (list of streams requested) + * 2) 1) 1) "1681749395006-0" <- list of indexes returned for stream + * 2) 1) "key1" + * 2) "value1" + * 2) 1) "1681749409349-0" + * 2) 1) "key2" + * 2) "value2" + * 3) "key2.2" + * 4) "value2.2" + * json equivalent: + * [ + * "mystream": [ + * { + * "1681749395006-0": { + * "key1": "value1" + * } + * }, + * { + * "1681749409349-0": { + * "key2": "value2", + * "key2.2": "value2.2" + * } + * } + * ] + * ] + */ +static rsRetVal handleRedisXREADReply(instanceConf_t *const inst, const redisReply *reply) { + DEFiRet; + redisReply *streamObj = NULL, *msgList = NULL, *msgObj = NULL; + + if(reply == NULL || reply->type != REDIS_REPLY_ARRAY) { + /* we do not process empty or non-ARRAY lines */ + DBGPRINTF("handleRedisXREADReply: object is not an array, ignoring\n"); + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: object is not an array, ignoring"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } else { + // iterating on streams + for(size_t i = 0; i < reply->elements; i++) { + streamObj = reply->element[i]; + // object should contain the name of the stream, and an array containing the messages + if(streamObj->type != REDIS_REPLY_ARRAY || streamObj->elements != 2) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong object format, " + "object should contain the name of the stream and an array of messages"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + if(streamObj->element[0]->type != REDIS_REPLY_STRING) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field format, " + "first entry is not a string (supposed to be stream name)"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + msgList = streamObj->element[1]; + + if(msgList->type != REDIS_REPLY_ARRAY) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field format, " + "second entry is not an array (supposed to be list of messages for stream)"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + DBGPRINTF("handleRedisXREADReply: enqueuing messages for stream '%s'\n", + streamObj->element[0]->str); + + for(size_t j = 0; j < msgList->elements; j++) { + msgObj = msgList->element[j]; + // Object should contain the name of the index, and its content(s) + if(msgObj->type != REDIS_REPLY_ARRAY || msgObj->elements != 2) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong object " + "format, object should contain the index and its content(s)"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + if(msgObj->element[0]->type != REDIS_REPLY_STRING) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field " + "format, first entry should be a string (index name)"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + if(msgObj->type != REDIS_REPLY_ARRAY) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field " + "format, second entry should be an array (index content(s))"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + CHKiRet(enqueueRedisStreamReply(inst, msgObj)); + + // Update current stream index + memcpy(inst->streamReadFrom, msgObj->element[0]->str, msgObj->element[0]->len); + inst->streamReadFrom[msgObj->element[0]->len] = '\0'; + DBGPRINTF("handleRedisXREADReply: current stream index is %s\n", inst->streamReadFrom); + } + } + } + + DBGPRINTF("handleRedisXREADReply: finished enqueuing!\n"); +finalize_it: + RETiRet; +} + + +/* + * handle the hiredis Stream XAUTOCLAIM return object. The provided reply is + * not freed - this must be done by the caller. + * example of stream to parse: + * 1) "1681904437564-0" <- next index to use for XAUTOCLAIM + * 2) 1) 1) "1681904437525-0" <- list of indexes reclaimed + * 2) 1) "toto" + * 2) "tata" + * 2) 1) "1681904437532-0" + * 2) 1) "titi" + * 2) "tutu" + * 3) (empty) <- indexes that no longer exist, were deleted from the PEL + * json equivalent: + * "1681904437564-0": [ + * { + * "1681904437525-0": { + * "toto": "tata" + * } + * }, + * { + * "1681904437532-0": { + * "titi": "tutu" + * } + * } + * ] + */ +static rsRetVal handleRedisXAUTOCLAIMReply( + instanceConf_t *const inst, + const redisReply *reply, + char **autoclaimIndex) { + DEFiRet; + redisReply *msgList = NULL, *msgObj = NULL; + + if(reply == NULL || reply->type != REDIS_REPLY_ARRAY) { + /* we do not process empty or non-ARRAY lines */ + DBGPRINTF("handleRedisXAUTOCLAIMReply: object is not an array, ignoring\n"); + FINALIZE; + } else { + // Object should contain between 2 and 3 elements (depends on Redis server version) + if(reply->elements < 2 || reply->elements > 3) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: wrong number of fields, " + "cannot process entry"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + if(reply->element[0]->type != REDIS_REPLY_STRING) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: the first element " + "is not a string, cannot process entry"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + msgList = reply->element[1]; + + if(msgList->type != REDIS_REPLY_ARRAY) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: the second element " + "is not an array, cannot process entry"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + DBGPRINTF("handleRedisXAUTOCLAIMReply: re-claiming messages for stream '%s'\n", inst->key); + + for(size_t j = 0; j < msgList->elements; j++) { + msgObj = msgList->element[j]; + // Object should contain the name of the index, and its content(s) + if(msgObj->type != REDIS_REPLY_ARRAY || msgObj->elements != 2) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: wrong message " + "format, cannot process"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + if(msgObj->element[0]->type != REDIS_REPLY_STRING) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: first message " + "element not a string, cannot process"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + if(msgObj->type != REDIS_REPLY_ARRAY) { + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: second message " + "element not an array, cannot process"); + ABORT_FINALIZE(RS_RET_OK_WARN); + } + + CHKiRet(enqueueRedisStreamReply(inst, msgObj)); + } + + // Update current stream index with next index from XAUTOCLAIM + // No message has to be claimed after that if value is "0-0" + memcpy(*autoclaimIndex, reply->element[0]->str, reply->element[0]->len); + (*autoclaimIndex)[reply->element[0]->len] = '\0'; + DBGPRINTF("handleRedisXAUTOCLAIMReply: next stream index is %s\n", (*autoclaimIndex)); + } + + DBGPRINTF("handleRedisXAUTOCLAIMReply: finished re-claiming!\n"); +finalize_it: + RETiRet; +} + + +/* + * Read Redis stream + */ +rsRetVal redisStreamRead(instanceConf_t *inst) { + DEFiRet; + redisReply *reply = NULL; + uint replyType = 0; + sbool mustClaimIdle = 0; + char *autoclaimIndex = NULL; + + assert(inst != NULL); + + // Ensure stream group is created before reading from it + if(inst->streamConsumerGroup != NULL) { + CHKiRet(ensureConsumerGroupCreated(inst)); + } + + + if(inst->streamAutoclaimIdleTime != 0) { + DBGPRINTF("redisStreamRead: getting pending entries for stream '%s' from '%s', with idle time %d\n", + inst->key, inst->streamReadFrom, inst->streamAutoclaimIdleTime); + CHKmalloc(autoclaimIndex = calloc(1, STREAM_INDEX_STR_MAXLEN)); + // Cannot claim from '$', will have to claim from the beginning of the stream + if(inst->streamReadFrom[0] == '$') { + LogMsg(0, RS_RET_OK, LOG_WARNING, "Cannot claim pending entries from '$', " + "will have to claim from the beginning of the stream"); + memcpy(autoclaimIndex, "0-0", 4); + } else { + memcpy(autoclaimIndex, inst->streamReadFrom, STREAM_INDEX_STR_MAXLEN); + } + mustClaimIdle = 1; + } else { + DBGPRINTF("redisStreamRead: beginning to read stream '%s' from '%s'\n", + inst->key, inst->streamReadFrom); + } + + do { + if(inst->streamConsumerGroup == NULL) { + reply = (redisReply *)redisCommand(inst->conn, "XREAD COUNT %d BLOCK %d STREAMS %s %s", + BATCH_SIZE, + WAIT_TIME_MS, + inst->key, + inst->streamReadFrom); + } else { + if(mustClaimIdle) { + reply = (redisReply *)redisCommand(inst->conn, + "XAUTOCLAIM %s %s %s %d %s COUNT %d", + inst->key, + inst->streamConsumerGroup, + inst->streamConsumerName, + inst->streamAutoclaimIdleTime, + autoclaimIndex, + BATCH_SIZE); + } else { + + reply = (redisReply *)redisCommand(inst->conn, + "XREADGROUP GROUP %s %s COUNT %d BLOCK %d STREAMS %s >", + inst->streamConsumerGroup, + inst->streamConsumerName, + BATCH_SIZE, + WAIT_TIME_MS, + inst->key); + } + } + if(reply == NULL) { + LogError(0, RS_RET_REDIS_ERROR, "redisStreamRead: Error while trying to read stream '%s'", + inst->key); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + + replyType = reply->type; + switch(replyType) { + case REDIS_REPLY_ARRAY: + DBGPRINTF("reply is an array, proceeding...\n"); + if(mustClaimIdle) { + CHKiRet(handleRedisXAUTOCLAIMReply(inst, reply, &autoclaimIndex)); + if(!strncmp(autoclaimIndex, "0-0", 4)) { + DBGPRINTF("redisStreamRead: Caught up with pending messages, " + "getting back to regular reads\n"); + mustClaimIdle = 0; + } + } else { + CHKiRet(handleRedisXREADReply(inst, reply)); + } + break; + case REDIS_REPLY_NIL: + // replies are dequeued but are empty = end of list + if(mustClaimIdle) mustClaimIdle = 0; + break; + case REDIS_REPLY_ERROR: + // There is a problem with the key or the Redis instance + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisStreamRead: error " + "while reading stream(s) -> %s", reply->str); + srSleep(1, 0); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + default: + LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "redisStreamRead: unexpected " + "reply type: %s", REDIS_REPLIES[replyType%15]); + } + freeReplyObject(reply); + reply = NULL; + + // while input can run, continue with a new batch + } while (glbl.GetGlobalInputTermState() == 0); + + DBGPRINTF("redisStreamRead: finished to dequeue key '%s'\n", inst->key); + +finalize_it: + if(reply != NULL) + freeReplyObject(reply); + if(inst->conn != NULL) { + redisFree(inst->conn); + inst->conn = NULL; + inst->currentNode = NULL; + } + if(autoclaimIndex != NULL) + free(autoclaimIndex); + RETiRet; +} + + +/* + * Subscribe to Redis channel + */ +rsRetVal redisSubscribe(instanceConf_t *inst) { + DEFiRet; + + DBGPRINTF("redisSubscribe: subscribing to channel '%s'\n", inst->key); + int ret = redisAsyncCommand( + inst->aconn, + redisAsyncRecvCallback, + NULL, + "SUBSCRIBE %s", + inst->key); + + if (ret != REDIS_OK) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisSubscribe: Could not subscribe"); + ABORT_FINALIZE(RS_RET_REDIS_ERROR); + } + + // Will block on this function as long as connection is open and event loop is not stopped + event_base_dispatch(inst->evtBase); + DBGPRINTF("redisSubscribe: finished.\n"); + +finalize_it: + RETiRet; +} + + +/* + * generic worker function + */ +void workerLoop(struct imhiredisWrkrInfo_s *me) { + uint i; + DBGPRINTF("workerLoop: beginning of worker loop...\n"); + + // Connect first time without delay + if (me->inst->currentNode != NULL) { + rsRetVal ret = me->fnConnectMaster(me->inst); + if(ret != RS_RET_OK) { + LogMsg(0, ret, LOG_WARNING, "workerLoop: Could not connect successfully to master"); + } + } + + while(glbl.GetGlobalInputTermState() == 0) { + if (!me->fnIsConnected(me->inst)) { + /* + * Sleep 10 seconds before attempting to resume a broken connexion + * (sleep small amounts to avoid missing termination status) + */ + LogMsg(0, RS_RET_OK, LOG_INFO, "workerLoop: " + "no valid connection, sleeping 10 seconds before retrying..."); + for(i = 0; i < 100; i++) { + // Rsyslog asked for shutdown, thread should be stopped + if (glbl.GetGlobalInputTermState() != 0) + goto end_loop; + // 100ms sleeps + srSleep(0, 100000); + } + + // search the current master node + if (me->inst->currentNode == NULL) { + if(RS_RET_OK != redisActualizeCurrentNode(me->inst)) + continue; + } + + // connect to current master + if (me->inst->currentNode != NULL) { + rsRetVal ret = me->fnConnectMaster(me->inst); + if(ret != RS_RET_OK) { + LogMsg(0, ret, LOG_WARNING, "workerLoop: " + "Could not connect successfully to master"); + } + } + } + if (me->fnIsConnected(me->inst)) { + me->fnRun(me->inst); + } + } + +end_loop: + return; +} + + +/* + * Workerthread function for a single hiredis consumer + */ +static void * +imhirediswrkr(void *myself) +{ + struct imhiredisWrkrInfo_s *me = (struct imhiredisWrkrInfo_s*) myself; + DBGPRINTF("imhiredis: started hiredis consumer workerthread\n"); + dbgPrintNode(me->inst->currentNode); + + if(me->inst->mode == IMHIREDIS_MODE_QUEUE) { + me->fnConnectMaster = connectMasterSync; + me->fnIsConnected = isConnectedSync; + me->fnRun = redisDequeue; + } + else if (me->inst->mode == IMHIREDIS_MODE_STREAM) { + me->fnConnectMaster = connectMasterSync; + me->fnIsConnected = isConnectedSync; + me->fnRun = redisStreamRead; + } + else if (me->inst->mode == IMHIREDIS_MODE_SUBSCRIBE) { + me->fnConnectMaster = connectMasterAsync; + me->fnIsConnected = isConnectedAsync; + me->fnRun = redisSubscribe; + } + + workerLoop(me); + + DBGPRINTF("imhiredis: stopped hiredis consumer workerthread\n"); + return NULL; +} + + + +// -------------------------- redisNode functions ----------------------------------- + +/* + * create a redisNode and set default values + * if a valid node is given as parameter, the new node is inserted as the new head of the linked list + */ +static rsRetVal +createRedisNode(redisNode **root) { + redisNode *node; + DEFiRet; + CHKmalloc(node = malloc(sizeof(redisNode))); + node->port = 0; + node->server = NULL; + node->socketPath = NULL; + node->usesSocket = 0; + node->isMaster = 0; + node->next = NULL; + + if ((*root) == NULL) { + *root = node; + } else { + node->next = (*root); + *root = node; + } + +finalize_it: + RETiRet; +} + +/* + * make a complete copy of the src node into the newly-created node in dst + * if dst already contains a node, the new node will be added as the new head of the provided list + * src should not be NULL + */ +rsRetVal copyNode(redisNode *src, redisNode **dst) { + DEFiRet; + + assert(src != NULL); + + CHKiRet(createRedisNode(dst)); + + (*dst)->isMaster = src->isMaster; + (*dst)->next = src->next; + (*dst)->port = src->port; + (*dst)->usesSocket = src->usesSocket; + + if (src->server) + (*dst)->server = (uchar *) strdup((const char *)src->server); + if (src->socketPath) + (*dst)->socketPath = (uchar *) strdup((const char *)src->socketPath); + +finalize_it: + RETiRet; +} + +/* + * free all ressources of the node + * will return next node if one is present, NULL otherwise + */ +redisNode *freeNode(redisNode *node) { + redisNode *ret = NULL; + if (node != NULL) { + if (node->next != NULL) + ret = node->next; + + if(node->server != NULL) + free(node->server); + if(node->socketPath != NULL) + free(node->socketPath); + free(node); + } + + return ret; +} + +/* + * insert node 'elem' after node 'root' in the linked list + * both root and elem should not be NULL + */ +void insertNodeAfter(redisNode *root, redisNode *elem) { + assert(root != NULL); + assert(elem != NULL); + + if(root->next != NULL) { + elem->next = root->next; + } + root->next = elem; + + return; +} + +void dbgPrintNode(redisNode *node) { + if (node != NULL) { + if (node->usesSocket) { + if (node->isMaster) { + DBGPRINTF("imhiredis: node is %s (master)\n", node->socketPath); + } else { + DBGPRINTF("imhiredis: node is %s (replica)\n", node->socketPath); + } + } else { + if (node->isMaster) { + DBGPRINTF("imhiredis: node is %s:%d (master)\n", node->server, node->port); + } else { + DBGPRINTF("imhiredis: node is %s:%d (replica)\n", node->server, node->port); + } + } + } + return; +} diff --git a/contrib/imhttp/Makefile.am b/contrib/imhttp/Makefile.am new file mode 100644 index 0000000..ce64dc4 --- /dev/null +++ b/contrib/imhttp/Makefile.am @@ -0,0 +1,5 @@ +pkglib_LTLIBRARIES = imhttp.la + +imhttp_la_SOURCES = imhttp.c +imhttp_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(APU_CFLAGS) +imhttp_la_LDFLAGS = -module -avoid-version $(CIVETWEB_LIBS) $(APU_LIBS) diff --git a/contrib/imhttp/Makefile.in b/contrib/imhttp/Makefile.in new file mode 100644 index 0000000..8eff726 --- /dev/null +++ b/contrib/imhttp/Makefile.in @@ -0,0 +1,795 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/imhttp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +imhttp_la_LIBADD = +am_imhttp_la_OBJECTS = imhttp_la-imhttp.lo +imhttp_la_OBJECTS = $(am_imhttp_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +imhttp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(imhttp_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imhttp_la-imhttp.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imhttp_la_SOURCES) +DIST_SOURCES = $(imhttp_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = imhttp.la +imhttp_la_SOURCES = imhttp.c +imhttp_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(APU_CFLAGS) +imhttp_la_LDFLAGS = -module -avoid-version $(CIVETWEB_LIBS) $(APU_LIBS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imhttp/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/imhttp/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +imhttp.la: $(imhttp_la_OBJECTS) $(imhttp_la_DEPENDENCIES) $(EXTRA_imhttp_la_DEPENDENCIES) + $(AM_V_CCLD)$(imhttp_la_LINK) -rpath $(pkglibdir) $(imhttp_la_OBJECTS) $(imhttp_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imhttp_la-imhttp.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +imhttp_la-imhttp.lo: imhttp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imhttp_la-imhttp.lo -MD -MP -MF $(DEPDIR)/imhttp_la-imhttp.Tpo -c -o imhttp_la-imhttp.lo `test -f 'imhttp.c' || echo '$(srcdir)/'`imhttp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imhttp_la-imhttp.Tpo $(DEPDIR)/imhttp_la-imhttp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imhttp.c' object='imhttp_la-imhttp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imhttp_la-imhttp.lo `test -f 'imhttp.c' || echo '$(srcdir)/'`imhttp.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/imhttp_la-imhttp.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/imhttp_la-imhttp.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/imhttp/imhttp.c b/contrib/imhttp/imhttp.c new file mode 100644 index 0000000..95704af --- /dev/null +++ b/contrib/imhttp/imhttp.c @@ -0,0 +1,1326 @@ +/* imhttp.c + * This is an input module for receiving http input. + * + * This file is contribution of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <stdarg.h> +#include <ctype.h> +#include <netinet/in.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/socket.h> +#include "rsyslog.h" +#include "cfsysline.h" /* access to config file objects */ +#include "module-template.h" +#include "ruleset.h" +#include "unicode-helper.h" +#include "rsyslog.h" +#include "errmsg.h" +#include "statsobj.h" +#include "ratelimit.h" +#include "dirty.h" + +#include "civetweb.h" +#include <apr_base64.h> +#include <apr_md5.h> + +MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imhttp") + +/* static data */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) +DEFobjCurrIf(statsobj) + +#define CIVETWEB_OPTION_NAME_PORTS "listening_ports" +#define CIVETWEB_OPTION_NAME_DOCUMENT_ROOT "document_root" +#define MAX_READ_BUFFER_SIZE 16384 +#define INIT_SCRATCH_BUF_SIZE 4096 +/* General purpose buffer size. */ +#define IMHTTP_MAX_BUF_LEN (8192) + +struct option { + const char *name; + const char *val; +}; + +struct auth_s { + char workbuf[IMHTTP_MAX_BUF_LEN]; + char* pworkbuf; + size_t workbuf_len; + char* pszUser; + char* pszPasswd; +}; + +struct data_parse_s { + sbool content_compressed; + sbool bzInitDone; /* did we do an init of zstrm already? */ + z_stream zstrm; /* zip stream to use for tcp compression */ + // Currently only used for octet specific parsing + enum { + eAtStrtFram, + eInOctetCnt, + eInMsg, + } inputState; + size_t iOctetsRemain; /* Number of Octets remaining in message */ + enum { + TCP_FRAMING_OCTET_STUFFING, + TCP_FRAMING_OCTET_COUNTING + } framingMode; +}; + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + instanceConf_t *root, *tail; + struct option ports; + struct option docroot; + struct option *options; + int nOptions; +}; + +struct instanceConf_s { + struct instanceConf_s *next; + uchar *pszBindRuleset; /* name of ruleset to bind to */ + uchar *pszEndpoint; /* endpoint to configure */ + uchar *pszBasicAuthFile; /* file containing basic auth users/pass */ + ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ + ratelimit_t *ratelimiter; + unsigned int ratelimitInterval; + unsigned int ratelimitBurst; + uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */ + prop_t *pInputName; + sbool flowControl; + sbool bDisableLFDelim; + sbool bSuppOctetFram; + sbool bAddMetadata; +}; + +struct conn_wrkr_s { + struct data_parse_s parseState; + uchar* pMsg; /* msg scratch buffer */ + size_t iMsg; /* index of next char to store in msg */ + uchar zipBuf[64*1024]; + multi_submit_t multiSub; + smsg_t *pMsgs[CONF_NUM_MULTISUB]; + char *pReadBuf; + size_t readBufSize; + prop_t *propRemoteAddr; + const struct mg_request_info *pri; /* do not free me - used to hold a reference only */ + char *pScratchBuf; + size_t scratchBufSize; +}; + +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */ +static prop_t *pInputName = NULL; + +//static size_t s_iMaxLine = 16; /* get maximum size we currently support */ +static size_t s_iMaxLine = 16384; /* get maximum size we currently support */ + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + { "ports", eCmdHdlrString, 0 }, + { "documentroot", eCmdHdlrString, 0 }, + { "liboptions", eCmdHdlrArray, 0 }, +}; + +static struct cnfparamblk modpblk = { + CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr +}; + +static struct cnfparamdescr inppdescr[] = { + { "endpoint", eCmdHdlrString, 0}, + { "basicauthfile", eCmdHdlrString, 0}, + { "ruleset", eCmdHdlrString, 0 }, + { "flowcontrol", eCmdHdlrBinary, 0 }, + { "disablelfdelimiter", eCmdHdlrBinary, 0 }, + { "supportoctetcountedframing", eCmdHdlrBinary, 0 }, + { "name", eCmdHdlrString, 0 }, + { "ratelimit.interval", eCmdHdlrInt, 0 }, + { "ratelimit.burst", eCmdHdlrInt, 0 }, + { "addmetadata", eCmdHdlrBinary, 0 } +}; + +#include "im-helper.h" /* must be included AFTER the type definitions! */ + +static struct cnfparamblk inppblk = { + CNFPARAMBLK_VERSION, + sizeof(inppdescr)/sizeof(struct cnfparamdescr), + inppdescr +}; + +static struct { + statsobj_t *stats; + STATSCOUNTER_DEF(ctrSubmitted, mutCtrSubmitted) + STATSCOUNTER_DEF(ctrFailed, mutCtrFailed); + STATSCOUNTER_DEF(ctrDiscarded, mutCtrDiscarded); +} statsCounter; + +#include "im-helper.h" /* must be included AFTER the type definitions! */ + +#define min(a, b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 +#define EXIT_URI "/exit" +volatile int exitNow = 0; + +struct mg_callbacks callbacks; + +typedef struct httpserv_s { + struct mg_context *ctx; + struct mg_callbacks callbacks; + const char **civetweb_options; + size_t civetweb_options_count; +} httpserv_t; + +static httpserv_t *s_httpserv; + +/* FORWARD DECLARATIONS */ +static rsRetVal processData(const instanceConf_t *const inst, + struct conn_wrkr_s *connWrkr, const char* buf, size_t len); + +static rsRetVal +createInstance(instanceConf_t **pinst) +{ + instanceConf_t *inst; + DEFiRet; + CHKmalloc(inst = calloc(1, sizeof(instanceConf_t))); + inst->next = NULL; + inst->pszBindRuleset = NULL; + inst->pBindRuleset = NULL; + inst->pszEndpoint = NULL; + inst->pszBasicAuthFile = NULL; + inst->ratelimiter = NULL; + inst->pszInputName = NULL; + inst->pInputName = NULL; + inst->ratelimitBurst = 10000; /* arbitrary high limit */ + inst->ratelimitInterval = 0; /* off */ + inst->flowControl = 1; + inst->bDisableLFDelim = 0; + inst->bSuppOctetFram = 0; + inst->bAddMetadata = 0; + // construct statsobj + + /* node created, let's add to config */ + if(loadModConf->tail == NULL) { + loadModConf->tail = loadModConf->root = inst; + } else { + loadModConf->tail->next = inst; + loadModConf->tail = inst; + } + + *pinst = inst; +finalize_it: + RETiRet; +} + +static rsRetVal +processCivetwebOptions(char *const param, + const char **const name, + const char **const paramval) +{ + DEFiRet; + char *val = strstr(param, "="); + if(val == NULL) { + LogError(0, RS_RET_PARAM_ERROR, "missing equal sign in " + "parameter '%s'", param); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + *val = '\0'; /* terminates name */ + ++val; /* now points to begin of value */ + CHKmalloc(*name = strdup(param)); + CHKmalloc(*paramval = strdup(val)); + +finalize_it: + RETiRet; +} + +static sbool valid_civetweb_option(const struct mg_option *valid_opts, const char* option) +{ + const struct mg_option *pvalid_opts = valid_opts; + for (; pvalid_opts != NULL && pvalid_opts->name != NULL; pvalid_opts++) { + if (strcmp(pvalid_opts->name, option) == 0) { + return TRUE; + } + } + return FALSE; +} + +#if 0 +static int +log_message(__attribute__((unused)) const struct mg_connection *conn, const char *message) +{ + puts(message); + return 1; +} +#endif +/* + * thread_type: + * 0 indicates the master thread + * 1 indicates a worker thread handling client connections + * 2 indicates an internal helper thread (timer thread) +*/ +static void* +init_thread(__attribute__((unused)) const struct mg_context *ctx, int thread_type) +{ + DEFiRet; + struct conn_wrkr_s *data = NULL; + if (thread_type == 1) { + CHKmalloc(data = calloc(1, sizeof(struct conn_wrkr_s))); + data->pMsg = NULL; + data->iMsg = 0; + data->parseState.bzInitDone = 0; + data->parseState.content_compressed = 0; + data->parseState.inputState = eAtStrtFram; + data->parseState.iOctetsRemain = 0; + data->multiSub.maxElem = CONF_NUM_MULTISUB; + data->multiSub.ppMsgs = data->pMsgs; + data->multiSub.nElem = 0; + data->pReadBuf = malloc(MAX_READ_BUFFER_SIZE); + data->readBufSize = MAX_READ_BUFFER_SIZE; + + data->parseState.bzInitDone = 0; + data->parseState.content_compressed = 0; + data->parseState.inputState = eAtStrtFram; + data->parseState.iOctetsRemain = 0; + + CHKmalloc(data->pMsg = calloc(1, 1 + s_iMaxLine)); + data->iMsg = 0; + data->propRemoteAddr = NULL; + data->pScratchBuf = NULL; + data->scratchBufSize = 0; + } + +finalize_it: + if (iRet != RS_RET_OK) { + free(data); + return NULL; + } + return data; +} + +static void +exit_thread(__attribute__((unused)) const struct mg_context *ctx, + __attribute__((unused)) int thread_type, void *thread_pointer) +{ + if (thread_type == 1) { + struct conn_wrkr_s *data = (struct conn_wrkr_s *) thread_pointer; + if (data->propRemoteAddr) { + prop.Destruct(&data->propRemoteAddr); + } + if (data->scratchBufSize) { + free(data->pScratchBuf); + } + free(data->pReadBuf); + free(data->pMsg); + free(data); + } +} + +static rsRetVal +msgAddMetadataFromHttpHeader(smsg_t *const __restrict__ pMsg, struct conn_wrkr_s *connWrkr) +{ + struct json_object *json = NULL; + DEFiRet; + const struct mg_request_info *ri = connWrkr->pri; + #define MAX_HTTP_HEADERS 64 /* hard limit */ + int count = min(ri->num_headers, MAX_HTTP_HEADERS); + + CHKmalloc(json = json_object_new_object()); + for (int i = 0 ; i < count ; i++ ) { + struct json_object *const jval = json_object_new_string(ri->http_headers[i].value); + CHKmalloc(jval); + /* truncate header names bigger than INIT_SCRATCH_BUF_SIZE */ + strncpy(connWrkr->pScratchBuf, ri->http_headers[i].name, connWrkr->scratchBufSize - 1); + /* make header lowercase */ + char* pname = connWrkr->pScratchBuf; + while (pname && *pname != '\0') { + *pname = tolower(*pname); + pname++; + } + json_object_object_add(json, (const char *const)connWrkr->pScratchBuf, jval); + } + CHKiRet(msgAddJSON(pMsg, (uchar*)"!metadata!httpheaders", json, 0, 0)); + +finalize_it: + if (iRet != RS_RET_OK && json) { + json_object_put(json); + } + RETiRet; +} + +static rsRetVal +msgAddMetadataFromHttpQueryParams(smsg_t *const __restrict__ pMsg, struct conn_wrkr_s *connWrkr) +{ + struct json_object *json = NULL; + DEFiRet; + const struct mg_request_info *ri = connWrkr->pri; + + if (ri && ri->query_string) { + strncpy(connWrkr->pScratchBuf, ri->query_string, connWrkr->scratchBufSize - 1); + char *pquery_str = connWrkr->pScratchBuf; + if (pquery_str) { + CHKmalloc(json = json_object_new_object()); + + char* saveptr = NULL; + char *kv_pair = strtok_r(pquery_str, "&;", &saveptr); + + for ( ; kv_pair != NULL; kv_pair = strtok_r(NULL, "&;", &saveptr)) { + char *saveptr2 = NULL; + char *key = strtok_r(kv_pair, "=", &saveptr2); + if (key) { + char *value = strtok_r(NULL, "=", &saveptr2); + struct json_object *const jval = json_object_new_string(value); + CHKmalloc(jval); + json_object_object_add(json, (const char *)key, jval); + } + } + CHKiRet(msgAddJSON(pMsg, (uchar*)"!metadata!queryparams", json, 0, 0)); + } + } +finalize_it: + if (iRet != RS_RET_OK && json) { + json_object_put(json); + } + RETiRet; +} + +static rsRetVal +doSubmitMsg(const instanceConf_t *const __restrict__ inst, + struct conn_wrkr_s *connWrkr, const uchar* msg, size_t len) +{ + smsg_t *pMsg; + DEFiRet; + + assert(len <= s_iMaxLine); + if (len == 0) { + DBGPRINTF("discarding zero-sized message\n"); + FINALIZE; + } + + CHKiRet(msgConstruct(&pMsg)); + MsgSetFlowControlType(pMsg, inst->flowControl + ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY); + if (inst->pInputName) { + MsgSetInputName(pMsg, inst->pInputName); + } else { + MsgSetInputName(pMsg, pInputName); + } + MsgSetRawMsg(pMsg, (const char*)msg, len); + MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ + if (connWrkr->propRemoteAddr) { + MsgSetRcvFromIP(pMsg, connWrkr->propRemoteAddr); + } + if (inst) { + MsgSetRuleset(pMsg, inst->pBindRuleset); + } + // TODO: make these flags configurable. + pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; + + if (inst->bAddMetadata) { + CHKiRet(msgAddMetadataFromHttpHeader(pMsg, connWrkr)); + CHKiRet(msgAddMetadataFromHttpQueryParams(pMsg, connWrkr)); + } + + ratelimitAddMsg(inst->ratelimiter, &connWrkr->multiSub, pMsg); + STATSCOUNTER_INC(statsCounter.ctrSubmitted, statsCounter.mutCtrSubmitted); +finalize_it: + connWrkr->iMsg = 0; + if (iRet != RS_RET_OK) { + STATSCOUNTER_INC(statsCounter.ctrDiscarded, statsCounter.mutCtrDiscarded); + } + RETiRet; +} + + +static rsRetVal +processOctetMsgLen(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, char ch) +{ + DEFiRet; + if (connWrkr->parseState.inputState == eAtStrtFram) { + if (inst->bSuppOctetFram && isdigit(ch)) { + connWrkr->parseState.inputState = eInOctetCnt; + connWrkr->parseState.iOctetsRemain = 0; + connWrkr->parseState.framingMode = TCP_FRAMING_OCTET_COUNTING; + } else { + connWrkr->parseState.inputState = eInMsg; + connWrkr->parseState.framingMode = TCP_FRAMING_OCTET_STUFFING; + } + } + + // parsing character. + if (connWrkr->parseState.inputState == eInOctetCnt) { + if (isdigit(ch)) { + if (connWrkr->parseState.iOctetsRemain <= 200000000) { + connWrkr->parseState.iOctetsRemain = connWrkr->parseState.iOctetsRemain * 10 + ch - '0'; + } + // temporarily save this character into the message buffer + if(connWrkr->iMsg + 1 < s_iMaxLine) { + connWrkr->pMsg[connWrkr->iMsg++] = ch; + } + } else { + const char *remoteAddr = ""; + if (connWrkr->propRemoteAddr) { + remoteAddr = (const char *)propGetSzStr(connWrkr->propRemoteAddr); + } + + /* handle space delimeter */ + if (ch != ' ') { + LogError(0, NO_ERRCODE, "Framing Error in received TCP message " + "from peer: (ip) %s: to input: %s, delimiter is not " + "SP but has ASCII value %d.", + remoteAddr, inst->pszInputName, ch); + } + + if (connWrkr->parseState.iOctetsRemain < 1) { + LogError(0, NO_ERRCODE, "Framing Error in received TCP message" + " from peer: (ip) %s: delimiter is not " + "SP but has ASCII value %d.", + remoteAddr, ch); + } else if (connWrkr->parseState.iOctetsRemain > s_iMaxLine) { + DBGPRINTF("truncating message with %lu octets - max msg size is %lu\n", + connWrkr->parseState.iOctetsRemain, s_iMaxLine); + LogError(0, NO_ERRCODE, "received oversize message from peer: " + "(hostname) (ip) %s: size is %lu bytes, max msg " + "size is %lu, truncating...", + remoteAddr, connWrkr->parseState.iOctetsRemain, s_iMaxLine); + } + connWrkr->parseState.inputState = eInMsg; + } + /* reset msg len for actual message processing */ + connWrkr->iMsg = 0; + /* retrieve next character */ + } + RETiRet; +} + +static rsRetVal +processOctetCounting(const instanceConf_t *const inst, + struct conn_wrkr_s *connWrkr, const char* buf, size_t len) +{ + DEFiRet; + const uchar* pbuf = (const uchar*)buf; + const uchar* pbufLast = pbuf + len; + + while (pbuf < pbufLast) { + char ch = *pbuf; + + if (connWrkr->parseState.inputState == eAtStrtFram || connWrkr->parseState.inputState == eInOctetCnt) { + processOctetMsgLen(inst, connWrkr, ch); + if (connWrkr->parseState.framingMode == TCP_FRAMING_OCTET_COUNTING) { + pbuf++; + } + } else if (connWrkr->parseState.inputState == eInMsg) { + if (connWrkr->parseState.framingMode == TCP_FRAMING_OCTET_STUFFING) { + if (connWrkr->iMsg < s_iMaxLine) { + if (ch == '\n') { + doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); + connWrkr->parseState.inputState = eAtStrtFram; + } else { + connWrkr->pMsg[connWrkr->iMsg++] = ch; + } + } else { + doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); + connWrkr->parseState.inputState = eAtStrtFram; + } + pbuf++; + } else { + assert (connWrkr->parseState.framingMode == TCP_FRAMING_OCTET_COUNTING); + /* parsing payload */ + size_t remainingBytes = pbufLast - pbuf; + // figure out how much is in block + size_t count = min (connWrkr->parseState.iOctetsRemain, remainingBytes); + if (connWrkr->iMsg + count >= s_iMaxLine) { + count = s_iMaxLine - connWrkr->iMsg; + } + + // just copy the bytes + if (count) { + memcpy(connWrkr->pMsg + connWrkr->iMsg, pbuf, count); + pbuf += count; + connWrkr->iMsg += count; + connWrkr->parseState.iOctetsRemain -= count; + } + + if (connWrkr->parseState.iOctetsRemain == 0) { + doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); + connWrkr->parseState.inputState = eAtStrtFram; + } + } + } else { + // unexpected + assert(0); + break; + } + } + RETiRet; +} + +static rsRetVal +processDisableLF(const instanceConf_t *const inst, + struct conn_wrkr_s *connWrkr, const char* buf, size_t len) +{ + DEFiRet; + const uchar *pbuf = (const uchar*)buf; + size_t remainingBytes = len; + const uchar* pbufLast = pbuf + len; + + while (pbuf < pbufLast) { + size_t count = 0; + if (connWrkr->iMsg + remainingBytes >= s_iMaxLine) { + count = s_iMaxLine - connWrkr->iMsg; + } else { + count = remainingBytes; + } + + if (count) { + memcpy(connWrkr->pMsg + connWrkr->iMsg, pbuf, count); + pbuf += count; + connWrkr->iMsg += count; + remainingBytes -= count; + } + doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); + } + RETiRet; +} + +static rsRetVal +processDataUncompressed(const instanceConf_t *const inst, + struct conn_wrkr_s *connWrkr, const char* buf, size_t len) +{ + const uchar *pbuf = (const uchar*)buf; + DEFiRet; + + if (inst->bDisableLFDelim) { + /* do block processing */ + iRet = processDisableLF(inst, connWrkr, buf, len); + } else if (inst->bSuppOctetFram) { + iRet = processOctetCounting(inst, connWrkr, buf, len); + } else { + const uchar* pbufLast = pbuf + len; + while (pbuf < pbufLast) { + char ch = *pbuf; + if (connWrkr->iMsg < s_iMaxLine) { + if (ch == '\n') { + doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); + } else { + connWrkr->pMsg[connWrkr->iMsg++] = ch; + } + } else { + doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); + } + pbuf++; + } + } + RETiRet; +} + +static rsRetVal +processDataCompressed(const instanceConf_t *const inst, + struct conn_wrkr_s *connWrkr, const char* buf, size_t len) +{ + DEFiRet; + + if (!connWrkr->parseState.bzInitDone) { + /* allocate deflate state */ + connWrkr->parseState.zstrm.zalloc = Z_NULL; + connWrkr->parseState.zstrm.zfree = Z_NULL; + connWrkr->parseState.zstrm.opaque = Z_NULL; + int rc = inflateInit2(&connWrkr->parseState.zstrm, (MAX_WBITS | 16)); + if (rc != Z_OK) { + dbgprintf("imhttp: error %d returned from zlib/inflateInit()\n", rc); + ABORT_FINALIZE(RS_RET_ZLIB_ERR); + } + connWrkr->parseState.bzInitDone = 1; + } + + connWrkr->parseState.zstrm.next_in = (Bytef*) buf; + connWrkr->parseState.zstrm.avail_in = len; + /* run inflate() on buffer until everything has been uncompressed */ + int outtotal = 0; + do { + int zRet = 0; + int outavail = 0; + dbgprintf("imhttp: in inflate() loop, avail_in %d, total_in %ld\n", + connWrkr->parseState.zstrm.avail_in, connWrkr->parseState.zstrm.total_in); + + connWrkr->parseState.zstrm.avail_out = sizeof(connWrkr->zipBuf); + connWrkr->parseState.zstrm.next_out = connWrkr->zipBuf; + zRet = inflate(&connWrkr->parseState.zstrm, Z_SYNC_FLUSH); + dbgprintf("imhttp: inflate(), ret: %d, avail_out: %d\n", zRet, connWrkr->parseState.zstrm.avail_out); + outavail = sizeof(connWrkr->zipBuf) - connWrkr->parseState.zstrm.avail_out; + if (outavail != 0) { + outtotal += outavail; + CHKiRet(processDataUncompressed(inst, connWrkr, (const char*)connWrkr->zipBuf, outavail)); + } + } while (connWrkr->parseState.zstrm.avail_out == 0); + + dbgprintf("imhttp: processDataCompressed complete, sizes: in %lld, out %llu\n", (long long) len, + (long long unsigned) outtotal); + +finalize_it: + RETiRet; +} + +static rsRetVal +processData(const instanceConf_t *const inst, + struct conn_wrkr_s *connWrkr, const char* buf, size_t len) +{ + DEFiRet; + + //inst->bDisableLFDelim = 0; + if (connWrkr->parseState.content_compressed) { + iRet = processDataCompressed(inst, connWrkr, buf, len); + } else { + iRet = processDataUncompressed(inst, connWrkr, buf, len); + } + + RETiRet; +} + +/* Return 1 on success. Always initializes the auth structure. */ +static int +parse_auth_header(struct mg_connection *conn, struct auth_s *auth) +{ + if (!auth || !conn) { + return 0; + } + + const char *auth_header = NULL; + if (((auth_header = mg_get_header(conn, "Authorization")) == NULL) || + strncasecmp(auth_header, "Basic ", 6) != 0) { + return 0; + } + + /* Parse authorization header */ + const char* src = auth_header + 6; + size_t len = apr_base64_decode_len((const char*)src); + auth->pworkbuf = auth->workbuf; + if (len > sizeof(auth->workbuf)) { + auth->pworkbuf = calloc(0, len); + auth->workbuf_len = len; + } + len = apr_base64_decode(auth->pworkbuf, src); + if (len == 0) { + return 0; + } + + char *passwd = NULL, *saveptr = NULL; + char *user = strtok_r(auth->pworkbuf, ":", &saveptr); + if (user) { + passwd = strtok_r(NULL, ":", &saveptr); + } + + auth->pszUser = user; + auth->pszPasswd = passwd; + + return 1; +} + +static int +read_auth_file(FILE* filep, struct auth_s *auth) +{ + if (!filep) { + return 0; + } + char workbuf[IMHTTP_MAX_BUF_LEN]; + size_t l = 0; + char* user; + char* passwd; + + while (fgets(workbuf, sizeof(workbuf), filep)) { + l = strnlen(workbuf, sizeof(workbuf)); + while (l > 0) { + if (isspace(workbuf[l-1]) || iscntrl(workbuf[l-1])) { + l--; + workbuf[l] = 0; + } else { + break; + } + } + + if (l < 1) { + continue; + } + + if (workbuf[0] == '#') { + continue; + } + + user = workbuf; + passwd = strchr(workbuf, ':'); + if (!passwd) { + continue; + } + *passwd = '\0'; + passwd++; + + if (!strcasecmp(auth->pszUser, user)) { + return (apr_password_validate(auth->pszPasswd, passwd) == APR_SUCCESS); + } + } + return 0; +} + +/* Authorize against the opened passwords file. Return 1 if authorized. */ +static int +authorize(struct mg_connection* conn, FILE* filep) +{ + if (!conn || !filep) { + return 0; + } + + struct auth_s auth = { .workbuf_len=0, .pworkbuf=NULL, .pszUser=NULL, .pszPasswd=NULL}; + if (!parse_auth_header(conn, &auth)) { + return 0; + } + + /* validate against htpasswd file */ + return read_auth_file(filep, &auth); +} + +/* Provides Basic Authorization handling that validates against a 'htpasswd' file. + see also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization +*/ +static int +basicAuthHandler(struct mg_connection *conn, void *cbdata) +{ + const instanceConf_t* inst = (const instanceConf_t*) cbdata; + char errStr[512]; + FILE *fp = NULL; + int ret = 1; + + if (!inst->pszBasicAuthFile) { + mg_cry(conn, "warning: 'BasicAuthFile' not configured.\n"); + ret = 0; + goto finalize; + } + + fp = fopen((const char *)inst->pszBasicAuthFile, "r"); + if (fp == NULL) { + if (strerror_r(errno, errStr, sizeof(errStr)) == 0) { + mg_cry(conn, + "error: 'BasicAuthFile' file '%s' could not be accessed: %s\n", + inst->pszBasicAuthFile, errStr); + } else { + mg_cry(conn, + "error: 'BasicAuthFile' file '%s' could not be accessed: %d\n", + inst->pszBasicAuthFile, errno); + } + ret = 0; + goto finalize; + } + + ret = authorize(conn, fp); + +finalize: + if (!ret) { + mg_send_http_error(conn, 401, "WWW-Authenticate: Basic realm=\"User Visible Realm\"\n"); + } + if (fp ) { + fclose(fp); + } + return ret; +} + +/* cbdata should actually contain instance data and we can actually use this instance data + * to hold reusable scratch buffer. + */ +static int +postHandler(struct mg_connection *conn, void *cbdata) +{ + int rc = 1; + instanceConf_t* inst = (instanceConf_t*) cbdata; + const struct mg_request_info *ri = mg_get_request_info(conn); + struct conn_wrkr_s *connWrkr = mg_get_thread_pointer(conn); + connWrkr->multiSub.nElem = 0; + memset(&connWrkr->parseState, 0, sizeof(connWrkr->parseState)); + connWrkr->pri = ri; + + if (inst->bAddMetadata && connWrkr->scratchBufSize == 0) { + connWrkr->pScratchBuf = calloc(1, INIT_SCRATCH_BUF_SIZE); + if (!connWrkr->pScratchBuf) { + mg_cry(conn, "%s() - could not alloc scratch buffer!\n", __FUNCTION__); + rc = 500; + FINALIZE; + } + connWrkr->scratchBufSize = INIT_SCRATCH_BUF_SIZE; + } + + if (0 != strcmp(ri->request_method, "POST")) { + /* Not a POST request */ + int ret = mg_get_request_link(conn, connWrkr->pReadBuf, connWrkr->readBufSize); + mg_printf(conn, + "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n"); + mg_printf(conn, "Content-Type: text/plain\r\n\r\n"); + mg_printf(conn, + "%s method not allowed in the POST handler\n", + ri->request_method); + if (ret >= 0) { + mg_printf(conn, + "use a web tool to send a POST request to %s\n", + connWrkr->pReadBuf); + } + STATSCOUNTER_INC(statsCounter.ctrFailed, statsCounter.mutCtrFailed); + rc = 405; + FINALIZE; + } + + if (ri->remote_addr[0] != '\0') { + size_t len = strnlen(ri->remote_addr, sizeof(ri->remote_addr)); + prop.CreateOrReuseStringProp(&connWrkr->propRemoteAddr, (const uchar*)ri->remote_addr, len); + } + + if (ri->content_length >= 0) { + /* We know the content length in advance */ + if (ri->content_length > (long long) connWrkr->readBufSize) { + connWrkr->pReadBuf = realloc(connWrkr->pReadBuf, ri->content_length+1); + if (!connWrkr->pReadBuf) { + mg_cry(conn, "%s() - realloc failed!\n", __FUNCTION__); + FINALIZE; + } + connWrkr->readBufSize = ri->content_length+1; + } + } else { + /* We must read until we find the end (chunked encoding + * or connection close), indicated my mg_read returning 0 */ + } + + if (ri->num_headers > 0) { + int i; + for (i = 0; i < ri->num_headers; i++) { + if (!strcasecmp(ri->http_headers[i].name, "content-encoding") && + !strcasecmp(ri->http_headers[i].value, "gzip")) { + connWrkr->parseState.content_compressed = 1; + } + } + } + + while (1) { + int count = mg_read(conn, connWrkr->pReadBuf, connWrkr->readBufSize); + if (count > 0) { + processData(inst, connWrkr, (const char*)connWrkr->pReadBuf, count); + } else { + break; + } + } + + /* submit remainder */ + doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); + multiSubmitFlush(&connWrkr->multiSub); + + mg_send_http_ok(conn, "text/plain", 0); + rc = 200; + +finalize_it: + if (connWrkr->parseState.bzInitDone) { + inflateEnd(&connWrkr->parseState.zstrm); + } + /* reset */ + connWrkr->iMsg = 0; + + return rc; +} + +static int runloop(void) +{ + dbgprintf("imhttp started.\n"); + + /* Add handler for form data */ + for(instanceConf_t *inst = runModConf->root ; inst != NULL ; inst = inst->next) { + assert(inst->pszEndpoint); + if (inst->pszEndpoint) { + dbgprintf("setting request handler: '%s'\n", inst->pszEndpoint); + mg_set_request_handler(s_httpserv->ctx, (char *)inst->pszEndpoint, postHandler, inst); + if (inst->pszBasicAuthFile) { + mg_set_auth_handler(s_httpserv->ctx, (char *)inst->pszEndpoint, basicAuthHandler, inst); + } + } + } + + /* Wait until the server should be closed */ + while(glbl.GetGlobalInputTermState() == 0) { + sleep(1); + } + return EXIT_SUCCESS; +} + +BEGINnewInpInst + struct cnfparamvals *pvals; + instanceConf_t *inst; + int i; +CODESTARTnewInpInst + DBGPRINTF("newInpInst (imhttp)\n"); + pvals = nvlstGetParams(lst, &inppblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, + "imhttp: required parameter are missing\n"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("input param blk in imtcp:\n"); + cnfparamsPrint(&inppblk, pvals); + } + + CHKiRet(createInstance(&inst)); + + for(i = 0 ; i < inppblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(inppblk.descr[i].name, "endpoint")) { + inst->pszEndpoint = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "basicauthfile")) { + inst->pszBasicAuthFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "ruleset")) { + inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "name")) { + inst->pszInputName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "ratelimit.burst")) { + inst->ratelimitBurst = (unsigned int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "ratelimit.interval")) { + inst->ratelimitInterval = (unsigned int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "flowcontrol")) { + inst->flowControl = (int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "disablelfdelimiter")) { + inst->bDisableLFDelim = (int) pvals[i].val.d.n; + } else if (!strcmp(inppblk.descr[i].name, "supportoctetcountedframing")) { + inst->bSuppOctetFram = (int) pvals[i].val.d.n; + } else if (!strcmp(inppblk.descr[i].name, "addmetadata")) { + inst->bAddMetadata = (int) pvals[i].val.d.n; + } else { + dbgprintf("imhttp: program error, non-handled " + "param '%s'\n", inppblk.descr[i].name); + } + } + + if (inst->pszInputName) { + CHKiRet(prop.Construct(&inst->pInputName)); + CHKiRet(prop.SetString(inst->pInputName, inst->pszInputName, ustrlen(inst->pszInputName))); + CHKiRet(prop.ConstructFinalize(inst->pInputName)); + } + CHKiRet(ratelimitNew(&inst->ratelimiter, "imphttp", NULL)); + ratelimitSetLinuxLike(inst->ratelimiter, inst->ratelimitInterval, inst->ratelimitBurst); + +finalize_it: +CODE_STD_FINALIZERnewInpInst + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; + loadModConf->ports.name = NULL; + loadModConf->docroot.name = NULL; + loadModConf->nOptions = 0; + loadModConf->options = NULL; +ENDbeginCnfLoad + + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "imhttp: error processing module " + "config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for imhttp:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(int i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(modpblk.descr[i].name, "ports")) { + assert(loadModConf->ports.name == NULL); + assert(loadModConf->ports.val == NULL); + loadModConf->ports.name = strdup(CIVETWEB_OPTION_NAME_PORTS); + loadModConf->ports.val = es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(modpblk.descr[i].name, "documentroot")) { + assert(loadModConf->docroot.name == NULL); + assert(loadModConf->docroot.val == NULL); + loadModConf->docroot.name = strdup(CIVETWEB_OPTION_NAME_DOCUMENT_ROOT); + loadModConf->docroot.val = es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "liboptions")) { + loadModConf->nOptions = pvals[i].val.d.ar->nmemb; + CHKmalloc(loadModConf->options = malloc(sizeof(struct option) * + pvals[i].val.d.ar->nmemb )); + for(int j = 0 ; j < pvals[i].val.d.ar->nmemb ; ++j) { + char *cstr = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); + CHKiRet(processCivetwebOptions(cstr, &loadModConf->options[j].name, + &loadModConf->options[j].val)); + free(cstr); + } + } else { + dbgprintf("imhttp: program error, non-handled " + "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); + } + } + +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + + +BEGINendCnfLoad +CODESTARTendCnfLoad + loadModConf = NULL; /* done loading */ +ENDendCnfLoad + +/* function to generate error message if framework does not find requested ruleset */ +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) +{ + LogError(0, NO_ERRCODE, "imhttp: ruleset '%s' for %s not found - " + "using default ruleset instead", inst->pszBindRuleset, + inst->pszEndpoint); +} + +BEGINcheckCnf + instanceConf_t *inst; +CODESTARTcheckCnf + for(inst = pModConf->root ; inst != NULL ; inst = inst->next) { + std_checkRuleset(pModConf, inst); + } + /* verify civetweb options are valid */ + const struct mg_option *valid_opts = mg_get_valid_options(); + for (int i = 0; i < pModConf->nOptions; ++i) { + if (!valid_civetweb_option(valid_opts, pModConf->options[i].name)) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "imhttp: module loaded, but " + "invalid civetweb option found - imhttp may not receive connections."); + iRet = RS_RET_CONF_PARSE_WARNING; + } + } +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; + + if (!s_httpserv) { + CHKmalloc(s_httpserv = calloc(1, sizeof(httpserv_t))); + } + /* options represents (key, value) so allocate 2x, and null terminated */ + size_t count = 1; + if (runModConf->ports.val) { + count += 2; + } + if (runModConf->docroot.val) { + count += 2; + } + count += (2 * runModConf->nOptions); + CHKmalloc(s_httpserv->civetweb_options = calloc(count, sizeof(*s_httpserv->civetweb_options))); + + const char **pcivetweb_options = s_httpserv->civetweb_options; + if (runModConf->nOptions) { + s_httpserv->civetweb_options_count = count; + for (int i = 0; i < runModConf->nOptions; ++i) { + *pcivetweb_options = runModConf->options[i].name; + pcivetweb_options++; + *pcivetweb_options = runModConf->options[i].val; + pcivetweb_options++; + } + } + /* append port, docroot */ + if (runModConf->ports.val) { + *pcivetweb_options = runModConf->ports.name; + pcivetweb_options++; + *pcivetweb_options = runModConf->ports.val; + pcivetweb_options++; + } + if (runModConf->docroot.val) { + *pcivetweb_options = runModConf->docroot.name; + pcivetweb_options++; + *pcivetweb_options = runModConf->docroot.val; + pcivetweb_options++; + } + + const char **option = s_httpserv->civetweb_options; + for (; option && *option != NULL; option++) { + dbgprintf("imhttp: civetweb option: %s\n", *option); + } + + CHKiRet(statsobj.Construct(&statsCounter.stats)); + CHKiRet(statsobj.SetName(statsCounter.stats, UCHAR_CONSTANT("imhttp"))); + CHKiRet(statsobj.SetOrigin(statsCounter.stats, UCHAR_CONSTANT("imhttp"))); + STATSCOUNTER_INIT(statsCounter.ctrSubmitted, statsCounter.mutCtrSubmitted); + CHKiRet(statsobj.AddCounter(statsCounter.stats, UCHAR_CONSTANT("submitted"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(statsCounter.ctrSubmitted))); + + STATSCOUNTER_INIT(statsCounter.ctrFailed, statsCounter.mutCtrFailed); + CHKiRet(statsobj.AddCounter(statsCounter.stats, UCHAR_CONSTANT("failed"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(statsCounter.ctrFailed))); + + STATSCOUNTER_INIT(statsCounter.ctrDiscarded, statsCounter.mutCtrDiscarded); + CHKiRet(statsobj.AddCounter(statsCounter.stats, UCHAR_CONSTANT("discarded"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(statsCounter.ctrDiscarded))); + + CHKiRet(statsobj.ConstructFinalize(statsCounter.stats)); + + /* init civetweb libs and start server w/no input */ + mg_init_library(MG_FEATURES_TLS); + memset(&callbacks, 0, sizeof(callbacks)); + //callbacks.log_message = log_message; + //callbacks.init_ssl = init_ssl; + callbacks.init_thread = init_thread; + callbacks.exit_thread = exit_thread; + s_httpserv->ctx = mg_start(&callbacks, NULL, s_httpserv->civetweb_options); + /* Check return value: */ + if (s_httpserv->ctx == NULL) { + LogError(0, RS_RET_INTERNAL_ERROR, "Cannot start CivetWeb - mg_start failed.\n"); + ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); + } + + finalize_it: + if (iRet != RS_RET_OK) { + free(s_httpserv); + s_httpserv = NULL; + LogError(0, NO_ERRCODE, "imhttp: error %d trying to activate configuration", iRet); + } + RETiRet; +ENDactivateCnf + +BEGINfreeCnf + instanceConf_t *inst, *del; +CODESTARTfreeCnf + for(inst = pModConf->root ; inst != NULL ; ) { + if (inst->ratelimiter) { + ratelimitDestruct(inst->ratelimiter); + } + if (inst->pInputName) { + prop.Destruct(&inst->pInputName); + } + free(inst->pszEndpoint); + free(inst->pszBasicAuthFile); + free(inst->pszBindRuleset); + free(inst->pszInputName); + + del = inst; + inst = inst->next; + free(del); + } + + for (int i = 0; i < pModConf->nOptions; ++i) { + free((void*) pModConf->options[i].name); + free((void*) pModConf->options[i].val); + } + free(pModConf->options); + + free((void*)pModConf->ports.name); + free((void*)pModConf->ports.val); + free((void*)pModConf->docroot.name); + free((void*)pModConf->docroot.val); + + if (statsCounter.stats) { + statsobj.Destruct(&statsCounter.stats); + } +ENDfreeCnf + + +/* This function is called to gather input. + */ +BEGINrunInput +CODESTARTrunInput + runloop(); +ENDrunInput + +/* initialize and return if will run or not */ +BEGINwillRun +CODESTARTwillRun +ENDwillRun + +BEGINafterRun +CODESTARTafterRun + if (s_httpserv) { + mg_stop(s_httpserv->ctx); + mg_exit_library(); + free(s_httpserv->civetweb_options); + free(s_httpserv); + } +ENDafterRun + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + // if(eFeat == sFEATURENonCancelInputTermination) + // iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +BEGINmodExit +CODESTARTmodExit + if(pInputName != NULL) { + prop.Destruct(&pInputName); + } + + /* release objects we used */ + objRelease(statsobj, CORE_COMPONENT); + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(ruleset, CORE_COMPONENT)); + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); + + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imhttp"), sizeof("imhttp") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); +ENDmodInit diff --git a/contrib/imkmsg/Makefile.am b/contrib/imkmsg/Makefile.am new file mode 100644 index 0000000..87c177d --- /dev/null +++ b/contrib/imkmsg/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = imkmsg.la +imkmsg_la_SOURCES = imkmsg.c imkmsg.h + +imkmsg_la_SOURCES += kmsg.c + +imkmsg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +imkmsg_la_LDFLAGS = -module -avoid-version +imkmsg_la_LIBADD = diff --git a/contrib/imkmsg/Makefile.in b/contrib/imkmsg/Makefile.in new file mode 100644 index 0000000..e58e4ff --- /dev/null +++ b/contrib/imkmsg/Makefile.in @@ -0,0 +1,807 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/imkmsg +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +imkmsg_la_DEPENDENCIES = +am_imkmsg_la_OBJECTS = imkmsg_la-imkmsg.lo imkmsg_la-kmsg.lo +imkmsg_la_OBJECTS = $(am_imkmsg_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +imkmsg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(imkmsg_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imkmsg_la-imkmsg.Plo \ + ./$(DEPDIR)/imkmsg_la-kmsg.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imkmsg_la_SOURCES) +DIST_SOURCES = $(imkmsg_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = imkmsg.la +imkmsg_la_SOURCES = imkmsg.c imkmsg.h kmsg.c +imkmsg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +imkmsg_la_LDFLAGS = -module -avoid-version +imkmsg_la_LIBADD = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imkmsg/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/imkmsg/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +imkmsg.la: $(imkmsg_la_OBJECTS) $(imkmsg_la_DEPENDENCIES) $(EXTRA_imkmsg_la_DEPENDENCIES) + $(AM_V_CCLD)$(imkmsg_la_LINK) -rpath $(pkglibdir) $(imkmsg_la_OBJECTS) $(imkmsg_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imkmsg_la-imkmsg.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imkmsg_la-kmsg.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +imkmsg_la-imkmsg.lo: imkmsg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imkmsg_la-imkmsg.lo -MD -MP -MF $(DEPDIR)/imkmsg_la-imkmsg.Tpo -c -o imkmsg_la-imkmsg.lo `test -f 'imkmsg.c' || echo '$(srcdir)/'`imkmsg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imkmsg_la-imkmsg.Tpo $(DEPDIR)/imkmsg_la-imkmsg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imkmsg.c' object='imkmsg_la-imkmsg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imkmsg_la-imkmsg.lo `test -f 'imkmsg.c' || echo '$(srcdir)/'`imkmsg.c + +imkmsg_la-kmsg.lo: kmsg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imkmsg_la-kmsg.lo -MD -MP -MF $(DEPDIR)/imkmsg_la-kmsg.Tpo -c -o imkmsg_la-kmsg.lo `test -f 'kmsg.c' || echo '$(srcdir)/'`kmsg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imkmsg_la-kmsg.Tpo $(DEPDIR)/imkmsg_la-kmsg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kmsg.c' object='imkmsg_la-kmsg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imkmsg_la-kmsg.lo `test -f 'kmsg.c' || echo '$(srcdir)/'`kmsg.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/imkmsg_la-imkmsg.Plo + -rm -f ./$(DEPDIR)/imkmsg_la-kmsg.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/imkmsg_la-imkmsg.Plo + -rm -f ./$(DEPDIR)/imkmsg_la-kmsg.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/imkmsg/imkmsg.c b/contrib/imkmsg/imkmsg.c new file mode 100644 index 0000000..9018b0b --- /dev/null +++ b/contrib/imkmsg/imkmsg.c @@ -0,0 +1,372 @@ +/* The kernel log module. + * + * This is rsyslog Linux only module for reading structured kernel logs. + * Module is based on imklog module so it retains its structure + * and other part is currently in kmsg.c file instead of this (imkmsg.c) + * For more information see that file. + * + * To test under Linux: + * echo test1 > /dev/kmsg + * + * Copyright (C) 2008-2023 Adiscon GmbH + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include <stdarg.h> +#include <ctype.h> +#include <stdlib.h> +#include <sys/socket.h> + +#include "dirty.h" +#include "cfsysline.h" +#include "obj.h" +#include "msg.h" +#include "module-template.h" +#include "datetime.h" +#include "imkmsg.h" +#include "net.h" +#include "glbl.h" +#include "prop.h" +#include "errmsg.h" +#include "unicode-helper.h" + +MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imkmsg") + +/* Module static data */ +DEF_IMOD_STATIC_DATA +DEFobjCurrIf(datetime) +DEFobjCurrIf(glbl) +DEFobjCurrIf(prop) +DEFobjCurrIf(net) + +/* config settings */ +typedef struct configSettings_s { + int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */ +} configSettings_t; +static configSettings_t cs; + +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */ +static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */ + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + { "parsekerneltimestamp", eCmdHdlrGetWord, 0 }, + { "readmode", eCmdHdlrGetWord, 0 }, + { "expectedbootcompleteseconds", eCmdHdlrPositiveInt, 0 } +}; +static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr + }; + +static prop_t *pInputName = NULL; +/* there is only one global inputName for all messages generated by this module */ +static prop_t *pLocalHostIP = NULL; /* a pseudo-constant propterty for 127.0.0.1 */ + +static inline void +initConfigSettings(void) +{ + cs.iFacilIntMsg = klogFacilIntMsg(); +} + + +/* enqueue the the kernel message into the message queue. + * The provided msg string is not freed - thus must be done + * by the caller. + * rgerhards, 2008-04-12 + */ +static rsRetVal +enqMsg(uchar *msg, uchar* pszTag, syslog_pri_t pri, struct timeval *tp, struct json_object *json) +{ + struct syslogTime st; + smsg_t *pMsg; + DEFiRet; + + assert(msg != NULL); + assert(pszTag != NULL); + + if(tp == NULL) { + CHKiRet(msgConstruct(&pMsg)); + } else { + datetime.timeval2syslogTime(tp, &st, TIME_IN_LOCALTIME); + CHKiRet(msgConstructWithTime(&pMsg, &st, tp->tv_sec)); + } + MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); + MsgSetInputName(pMsg, pInputName); + MsgSetRawMsgWOSize(pMsg, (char*)msg); + MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ + MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); + MsgSetRcvFromIP(pMsg, pLocalHostIP); + MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); + MsgSetTAG(pMsg, pszTag, ustrlen(pszTag)); + msgSetPRI(pMsg, pri); + pMsg->json = json; + CHKiRet(submitMsg2(pMsg)); + +finalize_it: + RETiRet; +} + + +/* log an imkmsg-internal message + * rgerhards, 2008-04-14 + */ +rsRetVal imkmsgLogIntMsg(syslog_pri_t priority, const char *fmt, ...) +{ + DEFiRet; + va_list ap; + uchar msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ + + va_start(ap, fmt); + vsnprintf((char*)msgBuf, sizeof(msgBuf), fmt, ap); + va_end(ap); + + logmsgInternal(NO_ERRCODE, priority, msgBuf, 0); + + RETiRet; +} + + +/* log a message from /dev/kmsg + */ +rsRetVal Syslog(syslog_pri_t priority, uchar *pMsg, struct timeval *tp, struct json_object *json) +{ + DEFiRet; + iRet = enqMsg((uchar*)pMsg, (uchar*) "kernel:", priority, tp, json); + RETiRet; +} + + +/* helper for some klog drivers which need to know the MaxLine global setting. They can + * not obtain it themselfs, because they are no modules and can not query the object hander. + * It would probably be a good idea to extend the interface to support it, but so far + * we create a (sufficiently valid) work-around. -- rgerhards, 2008-11-24 + */ +int klog_getMaxLine(void) +{ + return glbl.GetMaxLine(runModConf->pConf); +} + + +BEGINrunInput +CODESTARTrunInput + /* this is an endless loop - it is terminated when the thread is + * signalled to do so. This, however, is handled by the framework, + * right into the sleep below. + */ + while(!pThrd->bShallStop) { + /* klogLogKMsg() waits for the next kernel message, obtains it + * and then submits it to the rsyslog main queue. + * rgerhards, 2008-04-09 + */ + CHKiRet(klogLogKMsg(runModConf)); + } +finalize_it: +ENDrunInput + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; + /* init our settings */ + pModConf->iFacilIntMsg = klogFacilIntMsg(); + pModConf->parseKernelStamp = KMSG_PARSE_TS_STARTUP_ONLY; + pModConf->readMode = KMSG_READMODE_FULL_BOOT; + pModConf->expected_boot_complete_secs = 90; + loadModConf->configSetViaV2Method = 0; + bLegacyCnfModGlobalsPermitted = 1; + /* init legacy config vars */ + initConfigSettings(); +ENDbeginCnfLoad + + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module " + "config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for imkmsg:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(modpblk.descr[i].name, "parsekerneltimestamp")) { + if( !es_strconstcmp(pvals[i].val.d.estr, "on") + || !es_strconstcmp(pvals[i].val.d.estr, "always")) { + loadModConf->parseKernelStamp = KMSG_PARSE_TS_ALWAYS; + } else if(!es_strconstcmp(pvals[i].val.d.estr, "startup")) { + loadModConf->parseKernelStamp = KMSG_PARSE_TS_STARTUP_ONLY; + } else if(!es_strconstcmp(pvals[i].val.d.estr, "off")) { + loadModConf->parseKernelStamp = KMSG_PARSE_TS_OFF; + } else { + const char *const cstr = es_str2cstr(pvals[i].val.d.estr, NULL); + LogError(0, RS_RET_PARAM_ERROR, "imkmsg: unknown " + "parse mode '%s'", cstr); + free((void*)cstr); + } + } else if(!strcmp(modpblk.descr[i].name, "expectedbootcompleteseconds")) { + loadModConf->expected_boot_complete_secs = pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "readmode")) { + if(!es_strconstcmp(pvals[i].val.d.estr, "full-boot")) { + loadModConf->readMode = KMSG_READMODE_FULL_BOOT; + } else if(!es_strconstcmp(pvals[i].val.d.estr, "full-always")) { + loadModConf->readMode = KMSG_READMODE_FULL_ALWAYS; + } else if(!es_strconstcmp(pvals[i].val.d.estr, "new-only")) { + loadModConf->readMode = KMSG_READMODE_NEW_ONLY; + } else { + const char *const cstr = es_str2cstr(pvals[i].val.d.estr, NULL); + LogError(0, RS_RET_PARAM_ERROR, "imkmsg: unknown " + "read mode '%s', keeping default setting", cstr); + free((void*)cstr); + } + } else { + LogMsg(0, RS_RET_INTERNAL_ERROR, LOG_WARNING, + "imkmsg: RSYSLOG BUG, non-handled param '%s' in " + "beginCnfLoad\n", modpblk.descr[i].name); + } + } + + /* disable legacy module-global config directives */ + bLegacyCnfModGlobalsPermitted = 0; + loadModConf->configSetViaV2Method = 1; + +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + + +BEGINendCnfLoad +CODESTARTendCnfLoad + if(!loadModConf->configSetViaV2Method) { + /* persist module-specific settings from legacy config system */ + loadModConf->iFacilIntMsg = cs.iFacilIntMsg; + } + + loadModConf = NULL; /* done loading */ +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnfPrePrivDrop +CODESTARTactivateCnfPrePrivDrop + runModConf = pModConf; + iRet = klogWillRunPrePrivDrop(runModConf); +ENDactivateCnfPrePrivDrop + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + +BEGINwillRun +CODESTARTwillRun + iRet = klogWillRunPostPrivDrop(runModConf); +ENDwillRun + + +BEGINafterRun +CODESTARTafterRun + iRet = klogAfterRun(runModConf); +ENDafterRun + + +BEGINmodExit +CODESTARTmodExit + if(pInputName != NULL) + prop.Destruct(&pInputName); + if(pLocalHostIP != NULL) + prop.Destruct(&pLocalHostIP); + + /* release objects we used */ + objRelease(glbl, CORE_COMPONENT); + objRelease(net, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +ENDqueryEtryPt + +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + cs.iFacilIntMsg = klogFacilIntMsg(); + return RS_RET_OK; +} + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(datetime, CORE_COMPONENT)); + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(net, CORE_COMPONENT)); + + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.CreateStringProp(&pInputName, UCHAR_CONSTANT("imkmsg"), sizeof("imkmsg") - 1)); + CHKiRet(prop.CreateStringProp(&pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); + + /* init legacy config settings */ + initConfigSettings(); + + CHKiRet(omsdRegCFSLineHdlr((uchar *)"debugprintkernelsymbols", 0, eCmdHdlrGoneAway, + NULL, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrGoneAway, + NULL, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrGoneAway, + NULL, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrGoneAway, + NULL, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); +ENDmodInit diff --git a/contrib/imkmsg/imkmsg.h b/contrib/imkmsg/imkmsg.h new file mode 100644 index 0000000..0021f25 --- /dev/null +++ b/contrib/imkmsg/imkmsg.h @@ -0,0 +1,78 @@ +/* imkmsg.h + * These are the definitions for the kmsg message generation module. + * + * Copyright 2007-2023 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef IMKLOG_H_INCLUDED +#define IMKLOG_H_INCLUDED 1 + +#include "rsyslog.h" +#include "dirty.h" + +typedef enum _kernel_ts_parse_mods { + KMSG_PARSE_TS_OFF = 0, + KMSG_PARSE_TS_ALWAYS = 1, + KMSG_PARSE_TS_STARTUP_ONLY = 2 + } t_kernel_ts_parse_mode; + +typedef enum _kernel_readmode { + KMSG_READMODE_FULL_BOOT = 0, + KMSG_READMODE_FULL_ALWAYS = 1, + KMSG_READMODE_NEW_ONLY = 2 + } t_kernel_readmode; + +/* we need to have the modConf type present in all submodules */ +struct modConfData_s { + rsconf_t *pConf; + int iFacilIntMsg; + uchar *pszPath; + int console_log_level; + int expected_boot_complete_secs; + t_kernel_ts_parse_mode parseKernelStamp; + t_kernel_readmode readMode; + sbool configSetViaV2Method; +}; + +/* interface to "drivers" + * the platform specific drivers must implement these entry points. Only one + * driver may be active at any given time, thus we simply rely on the linker + * to resolve the addresses. + * rgerhards, 2008-04-09 + */ +rsRetVal klogLogKMsg(modConfData_t *pModConf); +rsRetVal klogWillRunPrePrivDrop(modConfData_t *pModConf); +rsRetVal klogWillRunPostPrivDrop(modConfData_t *pModConf); +rsRetVal klogAfterRun(modConfData_t *pModConf); +int klogFacilIntMsg(); + +/* the functions below may be called by the drivers */ +rsRetVal imkmsgLogIntMsg(syslog_pri_t priority, const char *fmt, ...) __attribute__((format(printf,2, 3))); +rsRetVal Syslog(syslog_pri_t priority, uchar *msg, struct timeval *tp, struct json_object *json); +int klogFacilIntMsg(void); + +/* prototypes */ +extern int klog_getMaxLine(void); /* work-around for klog drivers to get configured max line size */ +extern int InitKsyms(modConfData_t*); +extern void DeinitKsyms(void); +extern int InitMsyms(void); +extern void DeinitMsyms(void); +extern char * ExpandKadds(char *, char *); +extern void SetParanoiaLevel(int); + +#endif /* #ifndef IMKLOG_H_INCLUDED */ diff --git a/contrib/imkmsg/kmsg.c b/contrib/imkmsg/kmsg.c new file mode 100644 index 0000000..2548634 --- /dev/null +++ b/contrib/imkmsg/kmsg.c @@ -0,0 +1,327 @@ +/* imkmsg driver for Linux /dev/kmsg structured logging + * + * This contains Linux-specific functionality to read /dev/kmsg + * For a general overview, see head comment in imkmsg.c. + * This is heavily based on imklog bsd.c file. + * + * Copyright 2008-2023 Adiscon GmbH + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <sys/klog.h> +#include <sys/sysinfo.h> +#include <sys/time.h> +#include <json.h> + +#include "rsyslog.h" +#include "srUtils.h" +#include "debug.h" +#include "imkmsg.h" + +/* globals */ +static int fklog = -1; /* kernel log fd */ +static int bInInitialReading = 1; /* are we in the intial kmsg reading phase? */ +/* Note: There is a problem with kernel log time. + * See https://github.com/troglobit/sysklogd/commit/9f6fbb3301e571d8af95f8d771469291384e9e95 + * We use the same work-around if bFixKernelStamp is on, and use the kernel log time + * only for past records, which we assume to be from recent boot. Later on, we do not + * use them but system time. + * UNFORTUNATELY, with /dev/kmsg, we always get old messages on startup. That means we + * may also pull old messages. We do not address this right now, as for 10 years "old + * messages" was pretty acceptable. So we wait until someone complains. Hint: we could + * do a seek to the end of kmsg if desired to not pull old messages. + * 2023-10-31 rgerhards + */ + +#ifndef _PATH_KLOG +# define _PATH_KLOG "/dev/kmsg" +#endif + +/* submit a message to imkmsg Syslog() API. In this function, we parse + * necessary information from kernel log line, and make json string + * from the rest. + */ +static void +submitSyslog(modConfData_t *const pModConf, const uchar *buf) +{ + long offs = 0; + struct timeval tv; + struct timeval *tp = NULL; + struct sysinfo info; + unsigned long int timestamp = 0; + char name[1024]; + char value[1024]; + char msg[1024]; + syslog_pri_t priority = 0; + long int sequnum = 0; + struct json_object *json = NULL, *jval; + + /* create new json object */ + json = json_object_new_object(); + + /* get priority */ + for (; isdigit(*buf); buf++) { + priority = (priority * 10) + (*buf - '0'); + } + buf++; + + /* get messages sequence number and add it to json */ + for (; isdigit(*buf); buf++) { + sequnum = (sequnum * 10) + (*buf - '0'); + } + buf++; /* skip , */ + jval = json_object_new_int(sequnum); + json_object_object_add(json, "sequnum", jval); + + /* get timestamp */ + for (; isdigit(*buf); buf++) { + timestamp = (timestamp * 10) + (*buf - '0'); + } + + while (*buf != ';') { + buf++; /* skip everything till the first ; */ + } + buf++; /* skip ; */ + + /* get message */ + offs = 0; + for (; *buf != '\n' && *buf != '\0'; buf++, offs++) { + msg[offs] = *buf; + } + msg[offs] = '\0'; + jval = json_object_new_string((char*)msg); + json_object_object_add(json, "msg", jval); + + if (*buf != '\0') /* message has appended properties, skip \n */ + buf++; + + while (*buf) { + /* get name of the property */ + buf++; /* skip ' ' */ + offs = 0; + for (; *buf != '=' && *buf != ' '; buf++, offs++) { + name[offs] = *buf; + } + name[offs] = '\0'; + buf++; /* skip = or ' ' */; + + offs = 0; + for (; *buf != '\n' && *buf != '\0'; buf++, offs++) { + value[offs] = *buf; + } + value[offs] = '\0'; + if (*buf != '\0') { + buf++; /* another property, skip \n */ + } + + jval = json_object_new_string((char*)value); + json_object_object_add(json, name, jval); + } + + if( (pModConf->parseKernelStamp == KMSG_PARSE_TS_ALWAYS) + || ((pModConf->parseKernelStamp == KMSG_PARSE_TS_STARTUP_ONLY) && bInInitialReading) ) { + /* calculate timestamp */ + sysinfo(&info); + gettimeofday(&tv, NULL); + + /* get boot time */ + tv.tv_sec -= info.uptime; + + tv.tv_sec += timestamp / 1000000; + tv.tv_usec += timestamp % 1000000; + + while (tv.tv_usec < 0) { + tv.tv_sec--; + tv.tv_usec += 1000000; + } + + while (tv.tv_usec >= 1000000) { + tv.tv_sec++; + tv.tv_usec -= 1000000; + } + + tp = &tv; + } + + Syslog(priority, (uchar *)msg, tp, json); +} + + +/* open the kernel log - will be called inside the willRun() imkmsg entry point + */ +rsRetVal +klogWillRunPrePrivDrop(modConfData_t __attribute__((unused)) *pModConf) +{ + char errmsg[2048]; + DEFiRet; + + fklog = open(_PATH_KLOG, O_RDONLY | O_NONBLOCK, 0); + if (fklog < 0) { + imkmsgLogIntMsg(LOG_ERR, "imkmsg: cannot open kernel log (%s): %s.", + _PATH_KLOG, rs_strerror_r(errno, errmsg, sizeof(errmsg))); + ABORT_FINALIZE(RS_RET_ERR_OPEN_KLOG); + } + +finalize_it: + RETiRet; +} + +/* make sure the kernel log is readable after dropping privileges + */ +rsRetVal +klogWillRunPostPrivDrop(modConfData_t __attribute__((unused)) *pModConf) +{ + char errmsg[2048]; + int r; + DEFiRet; + + /* this normally returns EINVAL */ + /* on an OpenVZ VM, we get EPERM */ + r = read(fklog, NULL, 0); + if (r < 0 && errno != EINVAL && errno != EAGAIN && errno != EWOULDBLOCK) { + imkmsgLogIntMsg(LOG_ERR, "imkmsg: cannot open kernel log (%s): %s.", + _PATH_KLOG, rs_strerror_r(errno, errmsg, sizeof(errmsg))); + fklog = -1; + ABORT_FINALIZE(RS_RET_ERR_OPEN_KLOG); + } + +finalize_it: + RETiRet; +} + + +static void +change_reads_to_blocking(const int fd) +{ + const int flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); +} + +/* Read kernel log while data are available, each read() reads one + * record of printk buffer. + */ +static void +readkmsg(modConfData_t *const pModConf) +{ + int i; + uchar pRcv[16*1024+1]; + char errmsg[2048]; + off_t seek_result = 0; + + if(pModConf->readMode == KMSG_READMODE_FULL_BOOT) { + struct sysinfo info; + sysinfo(&info); + DBGPRINTF("imkmsg: system uptime is %lld, expected %d\n", + (long long) info.uptime, pModConf->expected_boot_complete_secs); + if(info.uptime > pModConf->expected_boot_complete_secs) { + seek_result = lseek(fklog, 0, SEEK_END); + } + } else if(pModConf->readMode == KMSG_READMODE_NEW_ONLY) { + seek_result = lseek(fklog, 0, SEEK_END); + } else if(pModConf->readMode != KMSG_READMODE_FULL_ALWAYS) { + imkmsgLogIntMsg(LOG_ERR, "imkmsg: internal program error, " + "unknown read mode %d, assuming 'full-always'", + pModConf->readMode); + } + + if(seek_result == (off_t) -1) { + imkmsgLogIntMsg(LOG_WARNING, + "imkmsg: could not seek to requested klog entries - will" + "now potentially output all messages"); + } + + for (;;) { + dbgprintf("imkmsg waiting for kernel log line\n"); + + /* every read() from the opened device node receives one record of the printk buffer */ + i = read(fklog, pRcv, 8192); + if (i > 0) { + /* successful read of message of nonzero length */ + pRcv[i] = '\0'; + } else if (i < 0 && errno == EPIPE) { + imkmsgLogIntMsg(LOG_WARNING, + "imkmsg: some messages in circular buffer got overwritten"); + continue; + } else { + /* something went wrong - error or zero length message */ + if(i < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + DBGPRINTF("imkmsg: initial read done, changing to blocking mode\n"); + change_reads_to_blocking(fklog); + bInInitialReading = 0; + continue; + } + if(i < 0 && errno != EINTR && errno != EAGAIN) { + /* error occurred */ + imkmsgLogIntMsg(LOG_ERR, + "imkmsg: error reading kernel log - shutting down: %s", + rs_strerror_r(errno, errmsg, sizeof(errmsg))); + fklog = -1; + } + break; + } + + submitSyslog(pModConf, pRcv); + } +} + + +/* to be called in the module's AfterRun entry point + * rgerhards, 2008-04-09 + */ +rsRetVal klogAfterRun(modConfData_t *pModConf) +{ + DEFiRet; + if(fklog != -1) + close(fklog); + /* Turn on logging of messages to console, but only if a log level was speficied */ + if(pModConf->console_log_level != -1) + klogctl(7, NULL, 0); + RETiRet; +} + + +/* to be called in the module's WillRun entry point, this is the main + * "message pull" mechanism. + * rgerhards, 2008-04-09 + */ +rsRetVal klogLogKMsg(modConfData_t *const pModConf) +{ + DEFiRet; + readkmsg(pModConf); + RETiRet; +} + + +/* provide the (system-specific) default facility for internal messages + * rgerhards, 2008-04-14 + */ +int +klogFacilIntMsg(void) +{ + return LOG_SYSLOG; +} + diff --git a/contrib/impcap/Makefile.am b/contrib/impcap/Makefile.am new file mode 100644 index 0000000..e1c80e5 --- /dev/null +++ b/contrib/impcap/Makefile.am @@ -0,0 +1,22 @@ +pkglib_LTLIBRARIES = impcap.la + +impcap_la_SOURCES = impcap.c +impcap_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +impcap_la_LDFLAGS = -module -avoid-version +impcap_la_LIBADD = -lpcap + +impcap_la_SOURCES += arp_parser.c +impcap_la_SOURCES += eth_parser.c +impcap_la_SOURCES += icmp_parser.c +impcap_la_SOURCES += ipv4_parser.c +impcap_la_SOURCES += ipv6_parser.c +impcap_la_SOURCES += ipx_parser.c +impcap_la_SOURCES += llc_parser.c +impcap_la_SOURCES += udp_parser.c +impcap_la_SOURCES += dns_parser.c +impcap_la_SOURCES += tcp_parser.c +impcap_la_SOURCES += smb_parser.c +impcap_la_SOURCES += ftp_parser.c +impcap_la_SOURCES += http_parser.c + +EXTRA_DIST=parsers.h diff --git a/contrib/impcap/Makefile.in b/contrib/impcap/Makefile.in new file mode 100644 index 0000000..506aaef --- /dev/null +++ b/contrib/impcap/Makefile.in @@ -0,0 +1,949 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/impcap +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +impcap_la_DEPENDENCIES = +am_impcap_la_OBJECTS = impcap_la-impcap.lo impcap_la-arp_parser.lo \ + impcap_la-eth_parser.lo impcap_la-icmp_parser.lo \ + impcap_la-ipv4_parser.lo impcap_la-ipv6_parser.lo \ + impcap_la-ipx_parser.lo impcap_la-llc_parser.lo \ + impcap_la-udp_parser.lo impcap_la-dns_parser.lo \ + impcap_la-tcp_parser.lo impcap_la-smb_parser.lo \ + impcap_la-ftp_parser.lo impcap_la-http_parser.lo +impcap_la_OBJECTS = $(am_impcap_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +impcap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(impcap_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/impcap_la-arp_parser.Plo \ + ./$(DEPDIR)/impcap_la-dns_parser.Plo \ + ./$(DEPDIR)/impcap_la-eth_parser.Plo \ + ./$(DEPDIR)/impcap_la-ftp_parser.Plo \ + ./$(DEPDIR)/impcap_la-http_parser.Plo \ + ./$(DEPDIR)/impcap_la-icmp_parser.Plo \ + ./$(DEPDIR)/impcap_la-impcap.Plo \ + ./$(DEPDIR)/impcap_la-ipv4_parser.Plo \ + ./$(DEPDIR)/impcap_la-ipv6_parser.Plo \ + ./$(DEPDIR)/impcap_la-ipx_parser.Plo \ + ./$(DEPDIR)/impcap_la-llc_parser.Plo \ + ./$(DEPDIR)/impcap_la-smb_parser.Plo \ + ./$(DEPDIR)/impcap_la-tcp_parser.Plo \ + ./$(DEPDIR)/impcap_la-udp_parser.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(impcap_la_SOURCES) +DIST_SOURCES = $(impcap_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = impcap.la +impcap_la_SOURCES = impcap.c arp_parser.c eth_parser.c icmp_parser.c \ + ipv4_parser.c ipv6_parser.c ipx_parser.c llc_parser.c \ + udp_parser.c dns_parser.c tcp_parser.c smb_parser.c \ + ftp_parser.c http_parser.c +impcap_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +impcap_la_LDFLAGS = -module -avoid-version +impcap_la_LIBADD = -lpcap +EXTRA_DIST = parsers.h +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/impcap/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/impcap/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +impcap.la: $(impcap_la_OBJECTS) $(impcap_la_DEPENDENCIES) $(EXTRA_impcap_la_DEPENDENCIES) + $(AM_V_CCLD)$(impcap_la_LINK) -rpath $(pkglibdir) $(impcap_la_OBJECTS) $(impcap_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-arp_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-dns_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-eth_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ftp_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-http_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-icmp_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-impcap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ipv4_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ipv6_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ipx_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-llc_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-smb_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-tcp_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-udp_parser.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +impcap_la-impcap.lo: impcap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-impcap.lo -MD -MP -MF $(DEPDIR)/impcap_la-impcap.Tpo -c -o impcap_la-impcap.lo `test -f 'impcap.c' || echo '$(srcdir)/'`impcap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-impcap.Tpo $(DEPDIR)/impcap_la-impcap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='impcap.c' object='impcap_la-impcap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-impcap.lo `test -f 'impcap.c' || echo '$(srcdir)/'`impcap.c + +impcap_la-arp_parser.lo: arp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-arp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-arp_parser.Tpo -c -o impcap_la-arp_parser.lo `test -f 'arp_parser.c' || echo '$(srcdir)/'`arp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-arp_parser.Tpo $(DEPDIR)/impcap_la-arp_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arp_parser.c' object='impcap_la-arp_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-arp_parser.lo `test -f 'arp_parser.c' || echo '$(srcdir)/'`arp_parser.c + +impcap_la-eth_parser.lo: eth_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-eth_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-eth_parser.Tpo -c -o impcap_la-eth_parser.lo `test -f 'eth_parser.c' || echo '$(srcdir)/'`eth_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-eth_parser.Tpo $(DEPDIR)/impcap_la-eth_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eth_parser.c' object='impcap_la-eth_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-eth_parser.lo `test -f 'eth_parser.c' || echo '$(srcdir)/'`eth_parser.c + +impcap_la-icmp_parser.lo: icmp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-icmp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-icmp_parser.Tpo -c -o impcap_la-icmp_parser.lo `test -f 'icmp_parser.c' || echo '$(srcdir)/'`icmp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-icmp_parser.Tpo $(DEPDIR)/impcap_la-icmp_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='icmp_parser.c' object='impcap_la-icmp_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-icmp_parser.lo `test -f 'icmp_parser.c' || echo '$(srcdir)/'`icmp_parser.c + +impcap_la-ipv4_parser.lo: ipv4_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ipv4_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ipv4_parser.Tpo -c -o impcap_la-ipv4_parser.lo `test -f 'ipv4_parser.c' || echo '$(srcdir)/'`ipv4_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ipv4_parser.Tpo $(DEPDIR)/impcap_la-ipv4_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipv4_parser.c' object='impcap_la-ipv4_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ipv4_parser.lo `test -f 'ipv4_parser.c' || echo '$(srcdir)/'`ipv4_parser.c + +impcap_la-ipv6_parser.lo: ipv6_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ipv6_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ipv6_parser.Tpo -c -o impcap_la-ipv6_parser.lo `test -f 'ipv6_parser.c' || echo '$(srcdir)/'`ipv6_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ipv6_parser.Tpo $(DEPDIR)/impcap_la-ipv6_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipv6_parser.c' object='impcap_la-ipv6_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ipv6_parser.lo `test -f 'ipv6_parser.c' || echo '$(srcdir)/'`ipv6_parser.c + +impcap_la-ipx_parser.lo: ipx_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ipx_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ipx_parser.Tpo -c -o impcap_la-ipx_parser.lo `test -f 'ipx_parser.c' || echo '$(srcdir)/'`ipx_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ipx_parser.Tpo $(DEPDIR)/impcap_la-ipx_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipx_parser.c' object='impcap_la-ipx_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ipx_parser.lo `test -f 'ipx_parser.c' || echo '$(srcdir)/'`ipx_parser.c + +impcap_la-llc_parser.lo: llc_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-llc_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-llc_parser.Tpo -c -o impcap_la-llc_parser.lo `test -f 'llc_parser.c' || echo '$(srcdir)/'`llc_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-llc_parser.Tpo $(DEPDIR)/impcap_la-llc_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='llc_parser.c' object='impcap_la-llc_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-llc_parser.lo `test -f 'llc_parser.c' || echo '$(srcdir)/'`llc_parser.c + +impcap_la-udp_parser.lo: udp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-udp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-udp_parser.Tpo -c -o impcap_la-udp_parser.lo `test -f 'udp_parser.c' || echo '$(srcdir)/'`udp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-udp_parser.Tpo $(DEPDIR)/impcap_la-udp_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='udp_parser.c' object='impcap_la-udp_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-udp_parser.lo `test -f 'udp_parser.c' || echo '$(srcdir)/'`udp_parser.c + +impcap_la-dns_parser.lo: dns_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-dns_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-dns_parser.Tpo -c -o impcap_la-dns_parser.lo `test -f 'dns_parser.c' || echo '$(srcdir)/'`dns_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-dns_parser.Tpo $(DEPDIR)/impcap_la-dns_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dns_parser.c' object='impcap_la-dns_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-dns_parser.lo `test -f 'dns_parser.c' || echo '$(srcdir)/'`dns_parser.c + +impcap_la-tcp_parser.lo: tcp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-tcp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-tcp_parser.Tpo -c -o impcap_la-tcp_parser.lo `test -f 'tcp_parser.c' || echo '$(srcdir)/'`tcp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-tcp_parser.Tpo $(DEPDIR)/impcap_la-tcp_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tcp_parser.c' object='impcap_la-tcp_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-tcp_parser.lo `test -f 'tcp_parser.c' || echo '$(srcdir)/'`tcp_parser.c + +impcap_la-smb_parser.lo: smb_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-smb_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-smb_parser.Tpo -c -o impcap_la-smb_parser.lo `test -f 'smb_parser.c' || echo '$(srcdir)/'`smb_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-smb_parser.Tpo $(DEPDIR)/impcap_la-smb_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smb_parser.c' object='impcap_la-smb_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-smb_parser.lo `test -f 'smb_parser.c' || echo '$(srcdir)/'`smb_parser.c + +impcap_la-ftp_parser.lo: ftp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ftp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ftp_parser.Tpo -c -o impcap_la-ftp_parser.lo `test -f 'ftp_parser.c' || echo '$(srcdir)/'`ftp_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ftp_parser.Tpo $(DEPDIR)/impcap_la-ftp_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp_parser.c' object='impcap_la-ftp_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ftp_parser.lo `test -f 'ftp_parser.c' || echo '$(srcdir)/'`ftp_parser.c + +impcap_la-http_parser.lo: http_parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-http_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-http_parser.Tpo -c -o impcap_la-http_parser.lo `test -f 'http_parser.c' || echo '$(srcdir)/'`http_parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-http_parser.Tpo $(DEPDIR)/impcap_la-http_parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_parser.c' object='impcap_la-http_parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-http_parser.lo `test -f 'http_parser.c' || echo '$(srcdir)/'`http_parser.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/impcap_la-arp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-dns_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-eth_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-ftp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-http_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-icmp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-impcap.Plo + -rm -f ./$(DEPDIR)/impcap_la-ipv4_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-ipv6_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-ipx_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-llc_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-smb_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-tcp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-udp_parser.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/impcap_la-arp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-dns_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-eth_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-ftp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-http_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-icmp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-impcap.Plo + -rm -f ./$(DEPDIR)/impcap_la-ipv4_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-ipv6_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-ipx_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-llc_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-smb_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-tcp_parser.Plo + -rm -f ./$(DEPDIR)/impcap_la-udp_parser.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/impcap/arp_parser.c b/contrib/impcap/arp_parser.c new file mode 100644 index 0000000..5d8ce6e --- /dev/null +++ b/contrib/impcap/arp_parser.c @@ -0,0 +1,163 @@ +/* arp_parser.c + * + * This file contains functions to parse ARP and RARP headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +struct arp_header_s { + uint16_t hwType; + uint16_t pType; + uint8_t hwAddrLen; + uint8_t pAddrLen; + uint16_t opCode; + uint8_t pAddr[]; +}; + +typedef struct arp_header_s arp_header_t; + +/* + * This function parses the bytes in the received packet to extract ARP metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the ARP header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where ARP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *arp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("arp_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 28) { /* too small for ARP header*/ + DBGPRINTF("ARP packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0); + } + + /* Union to prevent cast from uchar to arp_header_t */ + union { + const uchar *pck; + arp_header_t *hdr; + } arp_header_to_char; + + arp_header_to_char.pck = packet; + arp_header_t *arp_header = arp_header_to_char.hdr; + + char pAddrSrc[20], pAddrDst[20]; + + json_object_object_add(jparent, "ARP_hwType", json_object_new_int(ntohs(arp_header->hwType))); + json_object_object_add(jparent, "ARP_pType", json_object_new_int(ntohs(arp_header->pType))); + json_object_object_add(jparent, "ARP_op", json_object_new_int(ntohs(arp_header->opCode))); + + if (ntohs(arp_header->hwType) == 1) { /* ethernet addresses */ + char hwAddrSrc[20], hwAddrDst[20]; + + ether_ntoa_r((struct ether_addr *)arp_header->pAddr, hwAddrSrc); + ether_ntoa_r((struct ether_addr *)(arp_header->pAddr + arp_header->hwAddrLen + arp_header->pAddrLen), + hwAddrDst); + + json_object_object_add(jparent, "ARP_hwSrc", json_object_new_string((char *)hwAddrSrc)); + json_object_object_add(jparent, "ARP_hwDst", json_object_new_string((char *)hwAddrDst)); + } + + if (ntohs(arp_header->pType) == ETHERTYPE_IP) { + inet_ntop(AF_INET, (void *)(arp_header->pAddr + arp_header->hwAddrLen), pAddrSrc, 20); + inet_ntop(AF_INET, (void *)(arp_header->pAddr + 2 * arp_header->hwAddrLen + arp_header->pAddrLen), + pAddrDst, 20); + + json_object_object_add(jparent, "ARP_pSrc", json_object_new_string((char *)pAddrSrc)); + json_object_object_add(jparent, "ARP_pDst", json_object_new_string((char *)pAddrDst)); + } + + RETURN_DATA_AFTER(28); +} + +/* + * This function parses the bytes in the received packet to extract RARP metadata. + * This is a copy of ARP handler, as structure is the same but protocol code and name are different + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the RARP header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where RARP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *rarp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("rarp_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 28) { /* too small for RARP header*/ + DBGPRINTF("RARP packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0); + } + + /* Union to prevent cast from uchar to arp_header_t */ + union { + const uchar *pck; + arp_header_t *hdr; + } arp_header_to_char; + + arp_header_to_char.pck = packet; + arp_header_t *rarp_header = arp_header_to_char.hdr; + + char pAddrSrc[20], pAddrDst[20]; + + json_object_object_add(jparent, "RARP_hwType", json_object_new_int(ntohs(rarp_header->hwType))); + json_object_object_add(jparent, "RARP_pType", json_object_new_int(ntohs(rarp_header->pType))); + json_object_object_add(jparent, "RARP_op", json_object_new_int(ntohs(rarp_header->opCode))); + + if (ntohs(rarp_header->hwType) == 1) { /* ethernet addresses */ + char *hwAddrSrc = ether_ntoa((struct ether_addr *)rarp_header->pAddr); + char *hwAddrDst = ether_ntoa((struct ether_addr *)(rarp_header->pAddr + + rarp_header->hwAddrLen + + rarp_header->pAddrLen)); + + json_object_object_add(jparent, "RARP_hwSrc", json_object_new_string((char *)hwAddrSrc)); + json_object_object_add(jparent, "RARP_hwDst", json_object_new_string((char *)hwAddrDst)); + } + + if (ntohs(rarp_header->pType) == ETHERTYPE_IP) { + inet_ntop(AF_INET, (void *)(rarp_header->pAddr + rarp_header->hwAddrLen), pAddrSrc, 20); + inet_ntop(AF_INET, (void *)(rarp_header->pAddr + 2 * rarp_header->hwAddrLen + rarp_header->pAddrLen), + pAddrDst, 20); + + json_object_object_add(jparent, "RARP_pSrc", json_object_new_string((char *)pAddrSrc)); + json_object_object_add(jparent, "RARP_pDst", json_object_new_string((char *)pAddrDst)); + } + + RETURN_DATA_AFTER(28); +} diff --git a/contrib/impcap/dns_parser.c b/contrib/impcap/dns_parser.c new file mode 100644 index 0000000..f9f4e68 --- /dev/null +++ b/contrib/impcap/dns_parser.c @@ -0,0 +1,372 @@ +/* dns_parser.c + * + * This file contains functions to parse DNS headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Kevin Guillemot (kevin.guillemot@advens.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + + +/* List of RCodes defined in RFC6895 : https://tools.ietf.org/html/rfc6895 */ +static const char *dns_rcodes[] = { + "NoError", // 0 + "FormErr", // 1 + "ServFail", // 2 + "NXDomain", // 3 + "NotImp", // 4 + "Refused", // 5 + "YXDomain", // 6 + "YXRRSet", // 7 + "NXRRSet", // 8 + "NotAuth", // 9 + "NotZone", // 10 + "", // 11 - Reserved + "", // 12 - Reserved + "", // 13 - Reserved + "", // 14 - Reserved + "", // 15 - Reserved + "BADVERS|BADSIG", // 16 + "BADKEY", // 17 + "BADTIME", // 18 + "BADMODE", // 19 + "BADNAME", // 20 + "BADALG", // 21 + "BADTRUNC", // 22 + /* Reserved for private use */ + NULL +}; + +/* List of record types (maybe not complete) */ +static const char *dns_types[] = { + 0, + "A", // 1 + "NS", // 2 + "MD", // 3 + "MF", // 4 + "CNAME", // 5 + "SOA", // 6 + "MB", // 7 + "MG", // 8 + "MR", // 9 + "NULL", // 10 + "WKS", // 11 + "PTR", // 12 + "HINFO", // 13 + "MINFO", // 14 + "MX", // 15 + "TXT", // 16 + "RP", // 17 + "AFSDB", // 18 + "X25", // 19 + "ISDN", // 20 + "RT", // 21 + "NSAP", // 22 + "NSAP-PTR", // 23 + "SIG", // 24 + "KEY", // 25 + "PX", // 26 + "GPOS", // 27 + "AAAA", // 28 + "LOC", // 29 + "NXT", // 30 + "EID", // 31 + "NIMLOC", // 32 + "SRV", // 33 + "ATMA", // 34 + "NAPTR", // 35 + "KX", // 36 + "CERT", // 37 + "A6", // 38 + "DNAME", // 39 + "SINK", // 40 + "OPT", // 41 + "APL", // 42 + "DS", // 43 + "SSHFP", // 44 + "IPSECKEY", // 45 + "RRSIG", // 46 + "NSEC", // 47 + "DNSKEY", // 48 + "DHCID", // 49 + "NSEC3", // 50 + "NSEC3PARAM", // 51 + "TLSA", // 51 + "SMIMEA", // 52 + "Unassigned", // 53 + "HIP", // 53 + "NINFO", // 54 + "RKEY", // 55 + "TALINK", // 56 + "CDS", // 57 + "CDNSKEY", // 58 + "OPENPGPKEY", // 59 + "CSYNC", // 60 + "ZONEMD", // 61 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "SPF", // 99 + "UINFO", // 100 + "UID", // 101 + "GID", // 102 + "UNSPEC", // 103 + "NID", // 104 + "L32", // 105 + "L64", // 106 + "LP", // 107 + "EUI48", // 108 + "EUI64", // 109 + /* Reserved for private use */ + NULL +}; +/* Part 2, since 249. To prevent useless large buffer in memory */ +static const char *dns_types2[] = { + "TKEY", + "TSIG", + "IXFR", + "AXFR", + "MAILB", + "MAILA", + "*", + "URI", + "CAA", + "AVC", + "DOA", + "AMTRELAY", + NULL +}; +/* Part 3, since 32768. To prevent useless large buffer in memory */ +static const char *dns_types3[] = { + "TA", + "DLV", + NULL +}; + + +/* This function takes an integer as parameter + * and returns the corresponding string type of DNS query + */ +static const char *get_type(uint16_t x) { + const char **types = NULL; + uint16_t len_types3 = (sizeof(dns_types3) / sizeof(char *)) - 1; + uint16_t len_types2 = (sizeof(dns_types2) / sizeof(char *)) - 1; + uint16_t len_types = (sizeof(dns_types) / sizeof(char *)) - 1; + if (x >= 32768 && x < 32768 + len_types3) { + types = dns_types3; + x -= 32768; + } + else if (x >= 249 && x < 249 + len_types2) { + types = dns_types2; + x -= 249; + } + else if (x > 0 && x < len_types) + types = dns_types; + else + return "UNKNOWN"; + if (types[x] != NULL) + return types[x]; + return "UNKNOWN"; +} + + +/* This function takes an integer as parameter + * and returns the corresponding string class of DNS query + */ +static const char *get_class(uint16_t x) { + switch (x) { + case 1: + return "IN"; + case 3: + return "CH"; + case 4: + return "HS"; + case 254: + return "QCLASS NONE"; + case 255: + return "QCLASS *"; + } + return "UNKNOWN"; +} + + +/* + * This function parses the bytes in the received packet to extract DNS metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where DNS metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *dns_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + const uchar *packet_ptr = packet; + const uchar *end_packet = packet + pktSize; + DBGPRINTF("dns_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + /* Union to prevent cast from uchar to smb_header_t */ + union { + unsigned short int *two_bytes; + const uchar *pckt; + } union_short_int; + + /* Get transaction id */ + union_short_int.pckt = packet_ptr; + unsigned short int transaction_id = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("transaction_id = %02x \n", transaction_id); + union_short_int.pckt += 2; + + /* Get flags */ + unsigned short int flags = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("flags = %02x \n", flags); + + /* Get response flag */ + unsigned short int response_flag = (flags >> 15) & 0b1; // Get the left bit + //DBGPRINTF("response_flag = %02x \n", response_flag); + + /* Get Opcode */ + unsigned short int opcode = (flags >> 11) & 0b1111; + //DBGPRINTF("opcode = %02x \n", opcode); + + /* Verify Z: reserved bit */ + unsigned short int reserved = (flags >> 6) & 0b1; + //DBGPRINTF("reserved = %02x \n", reserved); + /* Reserved bit MUST be 0 */ + if (reserved != 0) { + DBGPRINTF("DNS packet reserved bit (Z) is not 0, aborting message. \n"); + RETURN_DATA_AFTER(0) + } + + /* Get reply code : 4 last bits */ + unsigned short int reply_code = flags & 0b1111; + //DBGPRINTF("reply_code = %02x \n", reply_code); + + union_short_int.pckt += 2; + + /* Get QDCOUNT */ + unsigned short int query_count = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("query_count = %02x \n", query_count); + union_short_int.pckt += 2; + + /* Get ANCOUNT */ + unsigned short int answer_count = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("answer_count = %02x \n", answer_count); + union_short_int.pckt += 2; + + /* Get NSCOUNT */ + unsigned short int authority_count = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("authority_count = %02x \n", authority_count); + union_short_int.pckt += 2; + + /* Get ARCOUNT */ + unsigned short int additionnal_count = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("additionnal_count = %02x \n", additionnal_count); + union_short_int.pckt += 2; + packet_ptr = union_short_int.pckt; + + fjson_object *queries = NULL; + if ((queries = json_object_new_array()) == NULL) { + DBGPRINTF("impcap::dns_parser: Cannot create new json array. Stopping.\n"); + RETURN_DATA_AFTER(0) + } + + // For each query of query_count + int query_cpt = 0; + while (query_cpt < query_count && packet_ptr < end_packet) { + size_t query_size = strnlen((const char *)packet_ptr, (size_t)(end_packet - packet_ptr)); + // Check if query is valid (max 255 bytes, plus a '\0') + if (query_size >= 256) { + DBGPRINTF("impcap::dns_parser: Length of domain queried is > 255. Stopping.\n"); + break; + } + // Check if remaining data is enough to hold query + '\0' + 4 bytes (QTYPE and QCLASS fields) + if (query_size + 5 > (size_t)(end_packet - packet_ptr)) { + DBGPRINTF("impcap::dns_parser: packet size too small to parse query. Stopping.\n"); + break; + } + fjson_object *query = NULL; + if ((query = json_object_new_object()) == NULL) { + DBGPRINTF("impcap::dns_parser: Cannot create new json object. Stopping.\n"); + break; + } + char domain_query[256] = {0}; + uchar nb_char = *packet_ptr; + packet_ptr++; + size_t cpt = 0; + while (cpt + 1 < query_size) { + if (nb_char == 0) { + nb_char = *packet_ptr; + domain_query[cpt] = '.'; + } else { + domain_query[cpt] = (char)*packet_ptr; + nb_char--; + } + cpt++; + packet_ptr++; + } + domain_query[cpt] = '\0'; + if (cpt) + packet_ptr++; // pass the last \0, only if query was not empty + // DBGPRINTF("Requested domain : '%s' \n", domain_query); + + /* Register the name in dict */ + json_object_object_add(query, "qname", json_object_new_string(domain_query)); + /* Get QTYPE */ + union_short_int.pckt = packet_ptr; + unsigned short int qtype = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("qtype = %02x \n", qtype); + json_object_object_add(query, "qtype", json_object_new_int((int)qtype)); + json_object_object_add(query, "type", json_object_new_string(get_type(qtype))); + union_short_int.pckt += 2; + /* Retrieve QCLASS */ + unsigned short int qclass = ntohs(*(union_short_int.two_bytes)); + //DBGPRINTF("qclass = %02x \n", qclass); + json_object_object_add(query, "qclass", json_object_new_int((int)qclass)); + json_object_object_add(query, "class", json_object_new_string(get_class(qclass))); + packet_ptr = union_short_int.pckt + 2; + /* Register the query in json array */ + json_object_array_add(queries, query); + query_cpt++; + } + + json_object_object_add(jparent, "DNS_transaction_id", json_object_new_int((int)transaction_id)); + + json_bool is_reponse = FALSE; + if (response_flag) + is_reponse = TRUE; + json_object_object_add(jparent, "DNS_response_flag", json_object_new_boolean(is_reponse)); + + json_object_object_add(jparent, "DNS_opcode", json_object_new_int(opcode)); + json_object_object_add(jparent, "DNS_rcode", json_object_new_int((int)reply_code)); + json_object_object_add(jparent, "DNS_error", json_object_new_string(dns_rcodes[reply_code])); + json_object_object_add(jparent, "DNS_QDCOUNT", json_object_new_int((int)query_count)); + json_object_object_add(jparent, "DNS_ANCOUNT", json_object_new_int((int)answer_count)); + json_object_object_add(jparent, "DNS_NSCOUNT", json_object_new_int((int)authority_count)); + json_object_object_add(jparent, "DNS_ARCOUNT", json_object_new_int((int)additionnal_count)); + json_object_object_add(jparent, "DNS_Names", queries); + + /* Packet has been successfully parsed, there still can be some responses left, but do not process them */ + RETURN_DATA_AFTER(0); +} diff --git a/contrib/impcap/eth_parser.c b/contrib/impcap/eth_parser.c new file mode 100644 index 0000000..4bda2d5 --- /dev/null +++ b/contrib/impcap/eth_parser.c @@ -0,0 +1,179 @@ +/* eth_parser.c + * + * This file contains functions to parse Ethernet II headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +struct __attribute__ ((__packed__)) eth_header_s { + uint8_t addrDst[6]; + uint8_t addrSrc[6]; + uint16_t type; +}; + +struct __attribute__ ((__packed__)) vlan_header_s { + uint8_t addrDst[6]; + uint8_t addrSrc[6]; + uint16_t vlanCode; + uint16_t vlanTag; + uint16_t type; +}; +#pragma GCC diagnostic pop + +typedef struct eth_header_s eth_header_t; +typedef struct vlan_header_s vlan_header_t; + + +/* + * Get an ethernet header type as uint16_t + * and return the correspondence as string + * NOTE : Only most common types are present, to complete if needed + */ +static const char *eth_type_to_string(uint16_t eth_type) { + switch (eth_type) { + case 0x00bb: // Extreme Networks Discovery Protocol + return "EDP"; + case 0x0200: // PUP protocol + return "PUP"; + case 0x0800: // IP protocol + return "IP"; + case 0x0806: // address resolution protocol + return "ARP"; + case 0x88a2: // AoE protocol + return "AOE"; + case 0x2000: // Cisco Discovery Protocol + return "CDP"; + case 0x2004: // Cisco Dynamic Trunking Protocol + return "DTP"; + case 0x8035: // reverse addr resolution protocol + return "REVARP"; + case 0x8100: // IEEE 802.1Q VLAN tagging + return "802.1Q"; + case 0x88a8: // IEEE 802.1ad + return "802.1AD"; + case 0x9100: // Legacy QinQ + return "QINQ1"; + case 0x9200: // Legacy QinQ + return "QINQ2"; + case 0x8137: // Internetwork Packet Exchange + return "IPX"; + case 0x86DD: // IPv6 protocol + return "IPv6"; + case 0x880B: // PPP + return "PPP"; + case 0x8847: // MPLS + return "MPLS"; + case 0x8848: // MPLS Multicast + return "MPLS_MCAST"; + case 0x8863: // PPP Over Ethernet Discovery Stage + return "PPPoE_DISC"; + case 0x8864: // PPP Over Ethernet Session Stage + return "PPPoE"; + case 0x88CC: // Link Layer Discovery Protocol + return "LLDP"; + case 0x6558: // Transparent Ethernet Bridging + return "TEB"; + default: + return "UNKNOWN"; + } +} + + +/* + * This function parses the bytes in the received packet to extract Ethernet II metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the ETH header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where ETH metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *eth_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("entered eth_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + if (pktSize < 14) { /* too short for eth header */ + DBGPRINTF("ETH packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0) + } + + eth_header_t *eth_header = (eth_header_t *)packet; + char ethMacSrc[20], ethMacDst[20]; + uint8_t hdrLen = 14; + + ether_ntoa_r((struct ether_addr *)eth_header->addrSrc, ethMacSrc); + ether_ntoa_r((struct ether_addr *)eth_header->addrDst, ethMacDst); + + json_object_object_add(jparent, "ETH_src", json_object_new_string((char *)ethMacSrc)); + json_object_object_add(jparent, "ETH_dst", json_object_new_string((char *)ethMacDst)); + + uint16_t ethType = (uint16_t)ntohs(eth_header->type); + + if (ethType == ETHERTYPE_VLAN) { + vlan_header_t *vlan_header = (vlan_header_t *)packet; + json_object_object_add(jparent, "ETH_tag", json_object_new_int(ntohs(vlan_header->vlanTag))); + ethType = (uint16_t)ntohs(vlan_header->type); + hdrLen += 4; + } + + data_ret_t *ret; + + if (ethType < 1500) { + /* this is a LLC header */ + json_object_object_add(jparent, "ETH_len", json_object_new_int(ethType)); + ret = llc_parse(packet + hdrLen, pktSize - hdrLen, jparent); + + /* packet has the minimum allowed size, so the remaining data is + * most likely padding, this should not appear as data, so remove it + * */ + //TODO this is a quick win, a more elaborate solution would be to check if all data + // is indeed zero, but that would take more processing time + if (pktSize <= 60 && ret->pData != NULL) { + if (!ret->pData[0]) ret->size = 0; + } + return ret; + } + + json_object_object_add(jparent, "ETH_type", json_object_new_int(ethType)); + json_object_object_add(jparent, "ETH_typestr", json_object_new_string((char *)eth_type_to_string(ethType))); + ret = eth_proto_parse(ethType, (packet + hdrLen), (pktSize - hdrLen), jparent); + + /* packet has the minimum allowed size, so the remaining data is + * most likely padding, this should not appear as data, so remove it */ + if (pktSize <= 60 && ret->pData != NULL) { + if (!ret->pData[0]) ret->size = 0; + } + return ret; +} diff --git a/contrib/impcap/ftp_parser.c b/contrib/impcap/ftp_parser.c new file mode 100644 index 0000000..6e724c9 --- /dev/null +++ b/contrib/impcap/ftp_parser.c @@ -0,0 +1,152 @@ +/* ftp_parser.c + * + * This file contains functions to parse FTP headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +static const int ftp_cds[] = { + 100, 110, 120, 125, 150, + 200, 202, 211, 212, 213, 214, 215, 220, 221, 225, 226, 227, 228, 229, 230, 231, 232, 250, 257, + 300, 331, 332, 350, + 400, 421, 425, 426, 430, 434, 450, 451, 452, + 500, 501, 502, 503, 504, 530, 532, 550, 551, 552, 553, + 600, 631, 632, 633, + 10000, 100054, 10060, 10061, 10066, 10068, + 0 +}; + +static const char *ftp_cmds[] = { + "STOR", + "TYPE", + "ABOR", + "ACCT", + "ALLO", + "APPE", + "CDUP", + "CWD", + "DELE", + "HELP", + "LIST", + "MKD", + "MODE", + "NLST", + "NOOP", + "PASS", + "PASV", + "PORT", + "PWD", + "QUIT", + "REIN", + "REST", + "RETR", + "RMD", + "RNFR", + "RNTO", + "SITE", + "SMNT", + "STAT", + "STOU", + "STRU", + "SYST", + "USER", + NULL +}; + +/* + * This function searches for a valid command in the header (from the list defined in ftp_cmds[]) + * and returns either the command or a NULL pointer +*/ +static const char *check_Command_ftp(uchar *first_part_packet) { + DBGPRINTF("in check_Command_ftp\n"); + DBGPRINTF("first_part_packet : '%s' \n", first_part_packet); + int i = 0; + for (i = 0; ftp_cmds[i] != NULL; i++) { + if (strncmp((const char *)first_part_packet, ftp_cmds[i], strlen((const char *)ftp_cmds[i]) + 1) == 0) { + return ftp_cmds[i]; + } + } + return "UNKNOWN"; +} + +/* + * This function searches for a valid code in the header (from the list defined in ftp_cds[]) + * and returns either the command or a NULL pointer +*/ +static int check_Code_ftp(uchar *first_part_packet) { + DBGPRINTF("in check_Code_ftp\n"); + DBGPRINTF("first_part_packet : %s \n", first_part_packet); + int i = 0; + for (i = 0; ftp_cds[i] != 0; i++) { + if (strtol((const char *)first_part_packet, NULL, 10) == ftp_cds[i]) { + return ftp_cds[i]; + } + } + return 0; +} + +/* + * This function parses the bytes in the received packet to extract FTP metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the FTP header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where FTP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *ftp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("ftp_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 5) { /* too short for ftp packet*/ + RETURN_DATA_AFTER(0) + } + uchar *packet2 = (uchar *)malloc(pktSize * sizeof(uchar)); + + memcpy(packet2, packet, pktSize); // strtok changes original packet + uchar *frst_part_ftp; + frst_part_ftp = (uchar *)strtok((char *)packet2, " "); // Get first part of packet ftp + strtok(NULL, "\r\n"); + + if (frst_part_ftp) { + int code = check_Code_ftp(frst_part_ftp); + const char *command = check_Command_ftp(frst_part_ftp); + if (code != 0) { + json_object_object_add(jparent, "FTP_response", json_object_new_int(code)); + } else if (command != NULL) { + json_object_object_add(jparent, "FTP_request", json_object_new_string(command)); + } + } + free(packet2); + RETURN_DATA_AFTER(0) +} diff --git a/contrib/impcap/http_parser.c b/contrib/impcap/http_parser.c new file mode 100644 index 0000000..56d8a25 --- /dev/null +++ b/contrib/impcap/http_parser.c @@ -0,0 +1,159 @@ +/* http_parser.c + * + * This file contains functions to parse HTTP headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +static const char *keywords[] = { + "OPTIONS", + "GET", + "HEAD", + "POST", + "PUT", + "DELETE", + "TRACE", + "CONNECT", + "HTTP", + NULL +}; + +static inline char *string_split(char **initString, const char *delimiterString) { + char *ret = *initString; + + if (*initString) { + char *pos = strstr(*initString, delimiterString); + if (pos) { + *initString = pos; + **initString = '\0'; + *initString += strlen(delimiterString); + } else { + *initString = NULL; + } + } + + return ret; +} + +static inline int has_status_keyword(char *http) { + const char *found; + int i; + + for (i = 0; keywords[i] != NULL; i++) { + found = strstr(http, keywords[i]); + if (found && (found - http) < 20) { + return 1; + } + } + + return 0; +} + +/* + * This function catches HTTP header fields and status line + * and adds them to the provided json object +*/ +static inline void catch_status_and_fields(char *header, struct json_object *jparent) { + DBGPRINTF("catch_status_and_fields\n"); + + struct json_object *fields = json_object_new_object(); + + char *statusLine = string_split(&header, "\r\n"); + char *firstPart, *secondPart, *thirdPart; + firstPart = string_split(&statusLine, " "); + secondPart = string_split(&statusLine, " "); + thirdPart = statusLine; + if (firstPart && secondPart && thirdPart) { + if (strstr(firstPart, "HTTP")) { + json_object_object_add(jparent, "HTTP_version", json_object_new_string(firstPart)); + json_object_object_add(jparent, "HTTP_status_code", json_object_new_string(secondPart)); + json_object_object_add(jparent, "HTTP_reason", json_object_new_string(thirdPart)); + } else { + json_object_object_add(jparent, "HTTP_method", json_object_new_string(firstPart)); + json_object_object_add(jparent, "HTTP_request_URI", json_object_new_string(secondPart)); + json_object_object_add(jparent, "HTTP_version", json_object_new_string(thirdPart)); + } + } + + char *fieldValue = string_split(&header, "\r\n"); + char *field, *value; + while (fieldValue) { + field = string_split(&fieldValue, ":"); + value = fieldValue; + if (value) { + while (*value == ' ') { value++; } + DBGPRINTF("got header field -> '%s': '%s'\n", field, value); + json_object_object_add(fields, field, json_object_new_string(value)); + } + + fieldValue = string_split(&header, "\r\n"); + } + + json_object_object_add(jparent, "HTTP_header_fields", fields); + + return; +} + +/* + * This function parses the bytes in the received packet to extract HTTP metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the beginning of the header will be checked by the function + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where HTTP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *http_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("http_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + if (pktSize < 6) { + RETURN_DATA_AFTER(0) + } + + char *pHttp = malloc(pktSize + 1); + char *http = pHttp; + memcpy(http, packet, pktSize); + *(http + pktSize) = '\0'; + + if (!has_status_keyword(http)) { + free(pHttp); + RETURN_DATA_AFTER(0) + } + + char *header = string_split(&http, "\r\n\r\n"); + + catch_status_and_fields(header, jparent); + + free(pHttp); + RETURN_DATA_AFTER(0) +} diff --git a/contrib/impcap/icmp_parser.c b/contrib/impcap/icmp_parser.c new file mode 100644 index 0000000..8a627ee --- /dev/null +++ b/contrib/impcap/icmp_parser.c @@ -0,0 +1,79 @@ +/* icmp_parser.c + * + * This file contains functions to parse ICMP headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +struct icmp_header_s { + uint8_t type; + uint8_t code; + uint16_t checksum; + uint8_t data[]; +}; + +typedef struct icmp_header_s icmp_header_t; + +/* + * This function parses the bytes in the received packet to extract ICMP metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the ICMP header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where ICMP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *icmp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("icmp_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 8) { + DBGPRINTF("ICMP packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0); + } + + /* Union to prevent cast from uchar to icmp_header_t */ + union { + const uchar *pck; + icmp_header_t *hdr; + } icmp_header_to_char; + + icmp_header_to_char.pck = packet; + icmp_header_t *icmp_header = icmp_header_to_char.hdr; + + json_object_object_add(jparent, "net_icmp_type", json_object_new_int(icmp_header->type)); + json_object_object_add(jparent, "net_icmp_code", json_object_new_int(icmp_header->code)); + json_object_object_add(jparent, "icmp_checksum", json_object_new_int(ntohs(icmp_header->checksum))); + + RETURN_DATA_AFTER(8) +} diff --git a/contrib/impcap/impcap.c b/contrib/impcap/impcap.c new file mode 100644 index 0000000..cdb1e54 --- /dev/null +++ b/contrib/impcap/impcap.c @@ -0,0 +1,748 @@ +/* impcap.c + * + * This is an input module using libpcap, a + * portable C/C++ library for network traffic capture. + * This module reads packets received from a network interface + * using libpcap, to extract information such as IP addresses, ports, + * protocols, etc... and make it available to rsyslog and other modules. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <stdarg.h> +#include <ctype.h> +#include <signal.h> +#include <json.h> + +#include <pcap.h> + +#include "rsyslog.h" +#include "prop.h" +#include "ruleset.h" +#include "datetime.h" + +#include "errmsg.h" +#include "unicode-helper.h" +#include "module-template.h" +#include "rainerscript.h" +#include "rsconf.h" +#include "glbl.h" +#include "srUtils.h" + +#include "parsers.h" + + +MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("impcap") + +#define DEFAULT_META_CONTAINER "!impcap" +#define DEFAULT_DATA_CONTAINER "!data" + + +/* static data */ +DEF_IMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) +DEFobjCurrIf(datetime) + +static prop_t *pInputName = NULL; + +char *stringToHex(char *string, size_t length); + +static ATTR_NORETURN void *startCaptureThread(void *instanceConf); + +/* conf structures */ + +struct instanceConf_s { + char *interface; + uchar *filePath; + pcap_t *device; + uchar *filter; + uchar *tag; + uint8_t promiscuous; + uint8_t immediateMode; + uint32_t bufSize; + uint8_t bufTimeout; + uint8_t pktBatchCnt; + pthread_t tid; + uchar *pszBindRuleset; /* name of ruleset to bind to */ + ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ + struct instanceConf_s *next; +}; + +struct modConfData_s { + rsconf_t *pConf; + instanceConf_t *root, *tail; + uint16_t snap_length; + uint8_t metadataOnly; + char *metadataContainer; + char *dataContainer; +}; + +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ + +/* input instance parameters */ +static struct cnfparamdescr inppdescr[] = { + {"interface", eCmdHdlrGetWord, 0}, + {"file", eCmdHdlrString, 0}, + {"promiscuous", eCmdHdlrBinary, 0}, + {"filter", eCmdHdlrString, 0}, + {"tag", eCmdHdlrString, 0}, + {"ruleset", eCmdHdlrString, 0}, + {"no_buffer", eCmdHdlrBinary, 0}, + {"buffer_size", eCmdHdlrPositiveInt, 0}, + {"buffer_timeout", eCmdHdlrPositiveInt, 0}, + {"packet_count", eCmdHdlrPositiveInt, 0} +}; +static struct cnfparamblk inppblk = { + CNFPARAMBLK_VERSION, + sizeof(inppdescr) / sizeof(struct cnfparamdescr), + inppdescr +}; + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + {"snap_length", eCmdHdlrPositiveInt, 0}, + {"metadata_only", eCmdHdlrBinary, 0}, + {"metadata_container", eCmdHdlrGetWord, 0}, + {"data_container", eCmdHdlrGetWord, 0} +}; +static struct cnfparamblk modpblk = { + CNFPARAMBLK_VERSION, + sizeof(modpdescr) / sizeof(struct cnfparamdescr), + modpdescr +}; + +#include "im-helper.h" + +/* + * create input instance, set default parameters, and + * add it to the list of instances. + */ +static rsRetVal +createInstance(instanceConf_t **pinst) { + instanceConf_t *inst; + DEFiRet; + CHKmalloc(inst = malloc(sizeof(instanceConf_t))); + inst->next = NULL; + inst->interface = NULL; + inst->filePath = NULL; + inst->device = NULL; + inst->promiscuous = 0; + inst->filter = NULL; + inst->tag = NULL; + inst->pszBindRuleset = NULL; + inst->immediateMode = 0; + inst->bufTimeout = 10; + inst->bufSize = 1024 * 1024 * 15; /* should be enough for up to 10Gb interface*/ + inst->pktBatchCnt = 5; + + /* node created, let's add to global config */ + if (loadModConf->tail == NULL) { + loadModConf->tail = loadModConf->root = inst; + } else { + loadModConf->tail->next = inst; + loadModConf->tail = inst; + } + + *pinst = inst; +finalize_it: + RETiRet; +} + +/* input instances */ + +BEGINnewInpInst +struct cnfparamvals *pvals; +instanceConf_t *inst; +int i; +CODESTARTnewInpInst + pvals = nvlstGetParams(lst, &inppblk, NULL); + + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, + "impcap: required parameters are missing\n"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CHKiRet(createInstance(&inst)); + + for (i = 0 ; i<inppblk.nParams ; ++i) { + if (!pvals[i].bUsed) + continue; + if (!strcmp(inppblk.descr[i].name, "interface")) { + inst->interface = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if (!strcmp(inppblk.descr[i].name, "file")) { + inst->filePath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if (!strcmp(inppblk.descr[i].name, "promiscuous")) { + inst->promiscuous = (uint8_t)pvals[i].val.d.n; + } + else if (!strcmp(inppblk.descr[i].name, "filter")) { + inst-> + filter = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if (!strcmp(inppblk.descr[i].name, "tag")) { + inst->tag = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if (!strcmp(inppblk.descr[i].name, "ruleset")) { + inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if (!strcmp(inppblk.descr[i].name, "no_buffer")) { + inst->immediateMode = (uint8_t)pvals[i].val.d.n; + } + else if (!strcmp(inppblk.descr[i].name, "buffer_size")) { + inst->bufSize = (uint32_t)pvals[i].val.d.n; + } + else if (!strcmp(inppblk.descr[i].name, "buffer_timeout")) { + inst->bufTimeout = (uint8_t)pvals[i].val.d.n; + } + else if (!strcmp(inppblk.descr[i].name, "packet_count")) { + inst->pktBatchCnt = (uint8_t)pvals[i].val.d.n; + } + else { + dbgprintf("impcap: non-handled param %s in beginCnfLoad\n", inppblk.descr[i].name); + } + } + +finalize_it: + +CODE_STD_FINALIZERnewInpInst + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + +/* global mod conf (v2 system) */ +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; + +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if (pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "impcap: error processing module " + "config parameters missing [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + for (i = 0 ; i<modpblk.nParams ; ++i) { + if (!pvals[i].bUsed) + continue; + if (!strcmp(modpblk.descr[i].name, "snap_length")) { + loadModConf->snap_length = (int)pvals[i].val.d.n; + } + else if (!strcmp(modpblk.descr[i].name, "metadata_only")) { + loadModConf->metadataOnly = (uint8_t)pvals[i].val.d.n; + } + else if (!strcmp(modpblk.descr[i].name, "metadata_container")) { + loadModConf->metadataContainer = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); + } + else if (!strcmp(modpblk.descr[i].name, "data_container")) { + loadModConf->dataContainer = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); + } + else { + dbgprintf("impcap: non-handled param %s in beginSetModCnf\n", modpblk.descr[i].name); + } + } + + if (!loadModConf->metadataContainer) + CHKmalloc(loadModConf->metadataContainer = strdup(DEFAULT_META_CONTAINER)); + + if (!loadModConf->dataContainer) + CHKmalloc(loadModConf->dataContainer = strdup(DEFAULT_DATA_CONTAINER)); +finalize_it: + if (pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + +/* config v2 system */ + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + loadModConf->pConf = pConf; + loadModConf->metadataOnly = 0; + loadModConf->snap_length = 65535; + loadModConf->metadataContainer = NULL; + loadModConf->dataContainer = NULL; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +/* function to generate error message if framework does not find requested ruleset */ +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) { + LogError(0, NO_ERRCODE, "impcap: ruleset '%s' for interface %s not found - " + "using default ruleset instead", inst->pszBindRuleset, + inst->interface); +} + +BEGINcheckCnf + instanceConf_t *inst; +CODESTARTcheckCnf + if (pModConf->root == NULL) { + LogError(0, RS_RET_NO_LISTNERS , "impcap: module loaded, but " + "no interface defined - no input will be gathered"); + iRet = RS_RET_NO_LISTNERS; + } + + if (pModConf->metadataOnly) { /* if metadata_only is "on", snap_length is overwritten */ + pModConf->snap_length = 100; /* arbitrary value, but should be enough for most protocols */ + } + + if (!pModConf->metadataContainer || !pModConf->dataContainer) { + LogError(0, RS_RET_LOAD_ERROR, "impcap: no name defined for metadata_container and " + "data_container, this shouldn't happen"); + } + else { + DBGPRINTF("impcap: metadata will be stored in '%s', and data in '%s'\n", + pModConf->metadataContainer, pModConf->dataContainer); + } + + for (inst = pModConf->root ; inst != NULL ; inst = inst->next) { + std_checkRuleset(pModConf, inst); + if (inst->interface ==NULL &&inst->filePath == NULL) { + iRet = RS_RET_INVALID_PARAMS; + LogError(0, RS_RET_LOAD_ERROR, "impcap: 'interface' or 'file' must be specified"); + break; + } + if (inst->interface !=NULL &&inst->filePath != NULL) { + iRet = RS_RET_INVALID_PARAMS; + LogError(0, RS_RET_LOAD_ERROR, "impcap: either 'interface' or 'file' must be specified"); + break; + } + } + +ENDcheckCnf + +BEGINactivateCnfPrePrivDrop +CODESTARTactivateCnfPrePrivDrop + runModConf = pModConf; +ENDactivateCnfPrePrivDrop + +BEGINactivateCnf + instanceConf_t *inst; + pcap_t *dev = NULL; + struct bpf_program filter_program; + bpf_u_int32 SubNet, NetMask; + char errBuf[PCAP_ERRBUF_SIZE]; + uint8_t retCode = 0; +CODESTARTactivateCnf + for (inst = pModConf->root ; inst != NULL ; inst = inst->next) { + if (inst->filePath != NULL) { + dev = pcap_open_offline((const char *)inst->filePath, errBuf); + if (dev == NULL) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while opening capture file: '%s'", errBuf); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + } + else if (inst->interface != NULL) { + dev = pcap_create((const char *)inst->interface, errBuf); + if (dev == NULL) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while creating packet capture: '%s'", + errBuf); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + + DBGPRINTF("setting snap_length %d\n", pModConf->snap_length); + if (pcap_set_snaplen(dev, pModConf->snap_length)) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting snap length: '%s'", + pcap_geterr(dev)); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + + DBGPRINTF("setting promiscuous %d\n", inst->promiscuous); + if (pcap_set_promisc(dev, inst->promiscuous)) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting promiscuous mode: '%s'", + pcap_geterr(dev)); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + + if (inst->immediateMode) { + DBGPRINTF("setting immediate mode %d\n", inst->immediateMode); + retCode = pcap_set_immediate_mode(dev, inst->immediateMode); + if (retCode) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting immediate mode: '%s'," + " using buffer instead\n",pcap_geterr(dev)); + } + } + + if (!inst->immediateMode || retCode){ + DBGPRINTF("setting buffer size %u \n", inst->bufSize); + if (pcap_set_buffer_size(dev, inst->bufSize)) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting buffer size: '%s'", + pcap_geterr(dev)); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + DBGPRINTF("setting buffer timeout %dms\n", inst->bufTimeout); + if (pcap_set_timeout(dev, inst->bufTimeout)) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting buffer timeout: '%s'", + pcap_geterr(dev)); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + } + + switch (pcap_activate(dev)) { + case PCAP_WARNING_PROMISC_NOTSUP: + LogError(0, NO_ERRCODE, "interface doesn't support promiscuous mode"); + break; + case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: + LogError(0, NO_ERRCODE, "timestamp type is not supported"); + break; + case PCAP_WARNING: + LogError(0, NO_ERRCODE, "pcap: %s", pcap_geterr(dev)); + break; + case PCAP_ERROR_ACTIVATED: + LogError(0, RS_RET_LOAD_ERROR, "already activated, shouldn't happen"); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + case PCAP_ERROR_NO_SUCH_DEVICE: + LogError(0, RS_RET_LOAD_ERROR, "device doesn't exist"); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + case PCAP_ERROR_PERM_DENIED: + LogError(0, RS_RET_LOAD_ERROR, "elevated privilege needed to open capture " + "interface"); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + case PCAP_ERROR_PROMISC_PERM_DENIED: + LogError(0, RS_RET_LOAD_ERROR, "elevated privilege needed to put interface " + "in promiscuous mode"); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + case PCAP_ERROR_RFMON_NOTSUP: + LogError(0, RS_RET_LOAD_ERROR, "interface doesn't support monitor mode"); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + case PCAP_ERROR_IFACE_NOT_UP: + LogError(0, RS_RET_LOAD_ERROR, "interface is not up"); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + case PCAP_ERROR: + LogError(0, RS_RET_LOAD_ERROR, "pcap: %s", pcap_geterr(dev)); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + + if (inst->filter != NULL) { + DBGPRINTF("getting netmask on %s\n", inst->interface); + //obtain the subnet + if (pcap_lookupnet(inst->interface, &SubNet, &NetMask, errBuf)){ + DBGPRINTF("could not get netmask\n"); + NetMask = PCAP_NETMASK_UNKNOWN; + } + DBGPRINTF("setting filter to '%s'\n", inst->filter); + /* Compile the filter */ + if (pcap_compile(dev, &filter_program, (const char *)inst->filter, 1, NetMask)) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while compiling filter: '%s'", + pcap_geterr(dev)); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + else if (pcap_setfilter(dev, &filter_program)) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting filter: '%s'", + pcap_geterr(dev)); + pcap_freecode(& filter_program); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + pcap_freecode(&filter_program); + } + + if (pcap_set_datalink(dev, DLT_EN10MB)) { + LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting datalink type: '%s'", + pcap_geterr(dev)); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + } /* inst->interface != NULL */ + else { + LogError(0, RS_RET_LOAD_ERROR, "impcap: no capture method specified, " + "please specify either 'interface' or 'file' in config"); + ABORT_FINALIZE(RS_RET_LOAD_ERROR); + } + + inst->device = dev; + } + +finalize_it: + if(iRet != 0) { + if(dev) pcap_close(dev); + } +ENDactivateCnf + +BEGINfreeCnf + instanceConf_t *inst, *del; +CODESTARTfreeCnf + DBGPRINTF("impcap: freeing confs...\n"); + for (inst = pModConf->root ; inst != NULL ; ) { + del = inst; + inst = inst->next; + free(del->filePath); + free(del->filter); + free(del->pszBindRuleset); + free(del->interface); + free(del->tag); + free(del); + } + free(pModConf->metadataContainer); + free(pModConf->dataContainer); + DBGPRINTF("impcap: finished freeing confs\n"); +ENDfreeCnf + +/* runtime functions */ + +/* + * Converts a list of bytes to their hexadecimal representation in ASCII + * + * Gets the list of bytes and the length as parameters + * + * Returns a pointer on the new list, being a string of ASCII characters + * representing hexadecimal values, in the form "A5B34C65..." + * its size is twice length parameter + 1 +*/ +char *stringToHex(char *string, size_t length) { + const char *hexChar = "0123456789ABCDEF"; + char *retBuf; + uint16_t i; + + retBuf = malloc((2 * length + 1) * sizeof(char)); + for (i = 0; i < length; ++i) { + retBuf[2 * i] = hexChar[(string[i] & 0xF0) >> 4]; + retBuf[2 * i + 1] = hexChar[string[i] & 0x0F]; + } + retBuf[2 * length] = '\0'; + + return retBuf; +} + +/* + * This method parses every packet received by libpcap, and is called by it + * It creates the message for Rsyslog, calls the parsers and add all necessary information + * in the message +*/ +void packet_parse(uchar *arg, const struct pcap_pkthdr *pkthdr, const uchar *packet) { + DBGPRINTF("impcap : entered packet_parse\n"); + smsg_t *pMsg; + + /* Prevent cast error from char to int with arg */ + union { + uchar *buf; + int *id; + } aux; + + aux.buf = arg; + int *id = aux.id; + msgConstruct(&pMsg); + + MsgSetInputName(pMsg, pInputName); + //search inst in loadmodconf,and check if there is tag. if so set tag in msg. + pthread_t ctid = pthread_self(); + instanceConf_t * inst; + for (inst = runModConf->root; inst != NULL; inst = inst->next) { + if (pthread_equal(ctid, inst->tid)) { + if (inst->pBindRuleset != NULL) { + MsgSetRuleset(pMsg, inst->pBindRuleset); + } + if (inst->tag != NULL) { + MsgSetTAG(pMsg, inst->tag, strlen((const char *)inst->tag)); + } + } + } + + + struct json_object *jown = json_object_new_object(); + json_object_object_add(jown, "ID", json_object_new_int(++(*id))); + + struct syslogTime sysTimePkt; + char timeStr[30]; + struct timeval tv = pkthdr->ts; + datetime.timeval2syslogTime(&tv, &sysTimePkt, 1/*inUTC*/); + if (datetime.formatTimestamp3339(&sysTimePkt, timeStr)) { + json_object_object_add(jown, "timestamp", json_object_new_string(timeStr)); + } + + json_object_object_add(jown, "net_bytes_total", json_object_new_int(pkthdr->len)); + + data_ret_t * dataLeft = eth_parse(packet, pkthdr->caplen, jown); + + json_object_object_add(jown, "net_bytes_data", json_object_new_int(dataLeft->size)); + char *dataHex = stringToHex(dataLeft->pData, dataLeft->size); + if (dataHex != NULL) { + struct json_object *jadd = json_object_new_object(); + json_object_object_add(jadd, "length", json_object_new_int(strlen(dataHex))); + json_object_object_add(jadd, "content", json_object_new_string(dataHex)); + msgAddJSON(pMsg, (uchar *)runModConf->dataContainer, jadd, 0, 0); + free(dataHex); + } + free(dataLeft); + + msgAddJSON(pMsg, (uchar *)runModConf->metadataContainer, jown, 0, 0); + submitMsg2(pMsg); +} + +/* This is used to terminate the plugin. + */ +static void +doSIGTTIN(int __attribute__((unused)) sig) +{ + pthread_t tid = pthread_self(); + const int bTerminate = ATOMIC_FETCH_32BIT(&bTerminateInputs, &mutTerminateInputs); + DBGPRINTF("impcap: awoken via SIGTTIN; bTerminateInputs: %d\n", bTerminate); + if(bTerminate) { + for(instanceConf_t *inst = runModConf->root; inst != NULL; inst = inst->next) { + if(pthread_equal(tid, inst->tid)) { + pcap_breakloop(inst->device); + DBGPRINTF("impcap: thread %lx, termination requested via SIGTTIN - telling libpcap\n", + (long unsigned int)tid); + } + } + } +} + +/* + * This is the main function for each thread + * taking care of a specified network interface +*/ +static ATTR_NORETURN void *startCaptureThread(void *instanceConf) { + int id = 0; + pthread_t tid = pthread_self(); + + /* we want to support non-cancel input termination. To do so, we must signal libpcap + * when to stop. As we run on the same thread, we need to register as SIGTTIN handler, + * which will be used to put the terminating condition into libpcap. + */ + DBGPRINTF("impcap: setting catch for SIGTTIN, thread %lx\n", + (long unsigned int)tid); + sigset_t sigSet; + struct sigaction sigAct; + sigfillset(&sigSet); + pthread_sigmask(SIG_BLOCK, &sigSet, NULL); + sigemptyset(&sigSet); + sigaddset(&sigSet, SIGTTIN); + pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL); + memset(&sigAct, 0, sizeof (sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = doSIGTTIN; + sigaction(SIGTTIN, &sigAct, NULL); + + instanceConf_t * inst = (instanceConf_t * )instanceConf; + DBGPRINTF("impcap: thread %lx, begin capture!\n", + (long unsigned int)tid); + while (glbl.GetGlobalInputTermState() == 0) { + pcap_dispatch(inst->device, inst->pktBatchCnt, packet_parse, (uchar * ) & id); + } + DBGPRINTF("impcap: thread %lx, capture finished\n", + (long unsigned int)tid); + pthread_exit(0); +} + +BEGINrunInput + instanceConf_t *inst; + int ret = 0; +CODESTARTrunInput + for (inst = runModConf->root ; inst != NULL ; inst = inst->next) { + /* creates a thread and starts capturing on the interface */ + ret = pthread_create(&inst->tid, NULL, startCaptureThread, inst); + if (ret) { + LogError(0, RS_RET_NO_RUN, "impcap: error while creating threads\n"); + } + } + + DBGPRINTF("impcap: starting to wait for close condition\n"); + // TODO: Use thread for capture instead of just waiting + while(glbl.GetGlobalInputTermState() == 0) { + if(glbl.GetGlobalInputTermState() == 0) + srSleep(0, 400000); + } + + DBGPRINTF("impcap: received close signal, signaling instance threads...\n"); + for (inst = runModConf->root; inst != NULL; inst = inst->next) { + pthread_kill(inst->tid, SIGTTIN); + } + + DBGPRINTF("impcap: threads signaled, waiting for join..."); + for (inst = runModConf->root ; inst != NULL ; inst = inst->next) { + pthread_join(inst->tid, NULL); + pcap_close(inst->device); + } + + DBGPRINTF("impcap: finished threads, stopping\n"); +ENDrunInput + +BEGINwillRun +CODESTARTwillRun +/* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("impcap"), sizeof("impcap") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); +finalize_it: +ENDwillRun + +BEGINafterRun +CODESTARTafterRun + if (pInputName != NULL) { + prop.Destruct(&pInputName); + } +ENDafterRun + +BEGINmodExit +CODESTARTmodExit + DBGPRINTF("impcap:: modExit\n"); + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + +/* declaration of functions */ + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURENonCancelInputTermination) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +BEGINqueryEtryPt +CODESTARTqueryEtryPt + CODEqueryEtryPt_STD_IMOD_QUERIES + CODEqueryEtryPt_STD_CONF2_QUERIES + CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES + CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES + CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES /* might need it */ + CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); +ENDmodInit diff --git a/contrib/impcap/ipv4_parser.c b/contrib/impcap/ipv4_parser.c new file mode 100644 index 0000000..2693c60 --- /dev/null +++ b/contrib/impcap/ipv4_parser.c @@ -0,0 +1,101 @@ +/* ipv4_parser.c + * + * This file contains functions to parse IP headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +struct ipv4_header_s { +/*#if __BYTE_ORDER == __BIG_ENDIAN + unsigned char version:4; + unsigned char ihl:4; +#else*/ + unsigned char ihl:4; + unsigned char version:4; +//#endif + uint8_t service; + uint16_t totLen; + uint16_t id; + uint16_t frag; + uint8_t ttl; + uint8_t proto; + uint16_t hdrChksum; + uint8_t addrSrc[4]; + uint8_t addrDst[4]; + uint8_t pOptions[]; +}; + +typedef struct ipv4_header_s ipv4_header_t; + +/* + * This function parses the bytes in the received packet to extract IP metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the IP header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where IP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *ipv4_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("ipv4_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 20) { /* too small for IPv4 header + data (header might be longer)*/ + DBGPRINTF("IPv4 packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0) + } + + /* Union to prevent cast from uchar to ipv4_header_t */ + union { + const uchar *pck; + ipv4_header_t *hdr; + } ipv4_header_to_char; + + ipv4_header_to_char.pck = packet; + ipv4_header_t *ipv4_header = ipv4_header_to_char.hdr; + + char addrSrc[20], addrDst[20]; + uint8_t hdrLen = 4 * ipv4_header->ihl; /* 4 x length in words */ + + inet_ntop(AF_INET, (void *)&ipv4_header->addrSrc, addrSrc, 20); + inet_ntop(AF_INET, (void *)&ipv4_header->addrDst, addrDst, 20); + + json_object_object_add(jparent, "net_dst_ip", json_object_new_string((char *)addrDst)); + json_object_object_add(jparent, "net_src_ip", json_object_new_string((char *)addrSrc)); + json_object_object_add(jparent, "IP_ihl", json_object_new_int(ipv4_header->ihl)); + json_object_object_add(jparent, "net_ttl", json_object_new_int(ipv4_header->ttl)); + json_object_object_add(jparent, "IP_proto", json_object_new_int(ipv4_header->proto)); + + + return ip_proto_parse(ipv4_header->proto, (packet + hdrLen), (pktSize - hdrLen), jparent); +} diff --git a/contrib/impcap/ipv6_parser.c b/contrib/impcap/ipv6_parser.c new file mode 100644 index 0000000..25c6b4c --- /dev/null +++ b/contrib/impcap/ipv6_parser.c @@ -0,0 +1,305 @@ +/* ipv6_parser.c + * + * This file contains functions to parse IPv6 headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +typedef struct __attribute__ ((__packed__)) ipv6_header_s { +#ifndef IPV6_VERSION_MASK +#define IPV6_VERSION_MASK 0xF0000000 +#endif +#ifndef IPV6_TC_MASK +#define IPV6_TC_MASK 0x0FF00000 +#endif +#ifndef IPV6_FLOW_MASK +#define IPV6_FLOW_MASK 0x000FFFFF +#endif + uint32_t vtf; + uint16_t dataLength; + uint8_t nextHeader; +#define IPV6_NHDR_HBH 0 +#define IPV6_NHDR_TCP 6 +#define IPV6_NHDR_UDP 17 +#define IPV6_NHDR_ENCIP6 41 +#define IPV6_NHDR_ROUT 43 +#define IPV6_NHDR_FRAG 44 +#define IPV6_NHDR_RRSV 46 +#define IPV6_NHDR_SEC 50 +#define IPV6_NHDR_AUTH 51 +#define IPV6_NHDR_ICMP6 58 +#define IPV6_NHDR_NONHDR 59 +#define IPV6_NHDR_DOPTS 60 + + uint8_t hopLimit; + uint8_t addrSrc[16]; + uint8_t addrDst[16]; +} ipv6_header_t; +#pragma GCC diagnostic pop + +#ifndef IPV6_VERSION +#define IPV6_VERSION(h) (ntohl(h->vtf) & IPV6_VERSION_MASK)>>28 +#endif +#ifndef IPV6_TC +#define IPV6_TC(h) (ntohl(h->vtf) & IPV6_TC_MASK)>>20 +#endif +#ifndef IPV6_FLOW +#define IPV6_FLOW(h) (ntohl(h->vtf) & IPV6_FLOW_MASK) +#endif + +/* extension headers */ +typedef struct hbh_header_s { + uint8_t nextHeader; + uint8_t hLength; + uint8_t *pOptions; +} hbh_header_t; + +typedef struct dest_header_s { + uint8_t nextHeader; + uint8_t hLength; + uint8_t *pOptions; +} dest_header_t; + +typedef struct route_header_s { + uint8_t nextHeader; + uint8_t hLength; + uint8_t rType; + uint8_t segsLeft; + uint32_t reserved; + uint8_t addrs[16]; +} route_header_t; + +typedef struct frag_header_s { + uint8_t nextHeader; + uint8_t reserved; + uint16_t offsetFlags; + uint32_t id; +} frag_header_t; + +static inline uint8_t hbh_header_parse(const uchar **packet, int *pktSize) { + DBGPRINTF("hbh_header_parse\n"); + + /* Union to prevent cast from uchar to hbh_header_t */ + union { + const uchar *pck; + hbh_header_t *hdr; + } hbh_header_to_char; + + hbh_header_to_char.pck = *packet; + hbh_header_t *hbh_header = hbh_header_to_char.hdr; + + /* hbh_header->hLength is the number of octets of header in 8-octet units minus 1 + * the header length SHOULD be a multiple of 8 */ + uint8_t hByteLength = hbh_header->hLength * 8 + 8; + DBGPRINTF("hByteLength: %d\n", hByteLength); + *pktSize -= hByteLength; + *packet += hByteLength; + + return hbh_header->nextHeader; +} + +static inline uint8_t dest_header_parse(const uchar **packet, int *pktSize) { + DBGPRINTF("dest_header_parse\n"); + + /* Union to prevent cast from uchar to dest_header_t */ + union { + const uchar *pck; + dest_header_t *hdr; + } dest_header_to_char; + + dest_header_to_char.pck = *packet; + dest_header_t *dest_header = dest_header_to_char.hdr; + + /* dest_header->hLength is the number of octets of header in 8-octet units minus 1 + * the header length SHOULD be a multiple of 8 */ + uint8_t hByteLength = dest_header->hLength * 8 + 8; + DBGPRINTF("hByteLength: %d\n", hByteLength); + *pktSize -= hByteLength; + *packet += hByteLength; + + return dest_header->nextHeader; +} + +static inline uint8_t route_header_parse(const uchar **packet, int *pktSize, struct json_object *jparent) { + DBGPRINTF("route_header_parse\n"); + + /* Union to prevent cast from uchar to route_header_t */ + union { + const uchar *pck; + route_header_t *hdr; + } route_header_to_char; + + route_header_to_char.pck = *packet; + route_header_t *route_header = route_header_to_char.hdr; + + /* route_header->hLength is the number of octets of header in 8-octet units minus 1 + * the header length (in bytes) SHOULD be a multiple of 8 */ + uint8_t hByteLength = route_header->hLength * 8 + 8; + *pktSize -= hByteLength; + *packet += hByteLength; + + if (route_header->rType == 0) { + json_object_object_add(jparent, "IP6_route_seg_left", json_object_new_int(route_header->segsLeft)); + + hByteLength -= 8; //leave only length of routing addresses + + char addrStr[40], routeFieldName[20]; + int addrNum = 1; + uint8_t *addr = &(route_header->addrs[0]); + + //while there is enough space for an IPv6 address + while (hByteLength >= 16) { + inet_ntop(AF_INET6, (void *)addr, addrStr, 40); + snprintf(routeFieldName, 20, "IP6_route_%d", addrNum++); + json_object_object_add(jparent, routeFieldName, json_object_new_string((char *)addrStr)); + + addr += 16; + hByteLength -= 16; + } + } + + return route_header->nextHeader; +} + +#define FRAG_OFFSET_MASK 0xFFF8 +#define MFLAG_MASK 0x0001 +static inline uint8_t frag_header_parse(const uchar **packet, int *pktSize, struct json_object *jparent) { + DBGPRINTF("frag_header_parse\n"); + + /* Union to prevent cast from uchar to frag_header_t */ + union { + const uchar *pck; + frag_header_t *hdr; + } frag_header_to_char; + + frag_header_to_char.pck = *packet; + frag_header_t *frag_header = frag_header_to_char.hdr; + + uint16_t flags = ntohs(frag_header->offsetFlags); + + json_object_object_add(jparent, "IP6_frag_offset", json_object_new_int((flags & FRAG_OFFSET_MASK) >> 3)); + json_object_object_add(jparent, "IP6_frag_more", json_object_new_boolean(flags & MFLAG_MASK)); + json_object_object_add(jparent, "IP6_frag_id", json_object_new_int64(frag_header->id)); + + *pktSize -= 8; + *packet += 8; + + return frag_header->nextHeader; +} + +/* + * This function parses the bytes in the received packet to extract IPv6 metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the IPv6 header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where IPv6 metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *ipv6_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("ipv6_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 40) { /* too small for IPv6 header + data (header might be longer)*/ + DBGPRINTF("IPv6 packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0) + } + + ipv6_header_t *ipv6_header = (ipv6_header_t *)packet; + + char addrSrc[40], addrDst[40]; + + inet_ntop(AF_INET6, (void *)&ipv6_header->addrSrc, addrSrc, 40); + inet_ntop(AF_INET6, (void *)&ipv6_header->addrDst, addrDst, 40); + + json_object_object_add(jparent, "net_dst_ip", json_object_new_string((char *)addrDst)); + json_object_object_add(jparent, "net_src_ip", json_object_new_string((char *)addrSrc)); + json_object_object_add(jparent, "net_ttl", json_object_new_int(ipv6_header->hopLimit)); + + uint8_t nextHeader = ipv6_header->nextHeader; + + packet += sizeof(ipv6_header_t); + pktSize -= sizeof(ipv6_header_t); + + DBGPRINTF("beginning ext headers scan\n"); + uint8_t hasNext = 1; + do { + switch (nextHeader) { + case IPV6_NHDR_HBH: + nextHeader = hbh_header_parse(&packet, &pktSize); + break; + case IPV6_NHDR_TCP: + json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); + return tcp_parse(packet, pktSize, jparent); + case IPV6_NHDR_UDP: + json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); + return udp_parse(packet, pktSize, jparent); + case IPV6_NHDR_ENCIP6: + hasNext = 0; + break; + case IPV6_NHDR_ROUT: + nextHeader = route_header_parse(&packet, &pktSize, jparent); + break; + case IPV6_NHDR_FRAG: + nextHeader = frag_header_parse(&packet, &pktSize, jparent); + break; + case IPV6_NHDR_RRSV: + hasNext = 0; + break; + case IPV6_NHDR_SEC: + hasNext = 0; + break; + case IPV6_NHDR_AUTH: + hasNext = 0; + break; + case IPV6_NHDR_ICMP6: + json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); + return icmp_parse(packet, pktSize, jparent); + case IPV6_NHDR_NONHDR: + hasNext = 0; + break; + case IPV6_NHDR_DOPTS: + nextHeader = dest_header_parse(&packet, &pktSize); + break; + default: + hasNext = 0; + break; + } + } while (hasNext); + + json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); + RETURN_DATA_AFTER(0) +} diff --git a/contrib/impcap/ipx_parser.c b/contrib/impcap/ipx_parser.c new file mode 100644 index 0000000..acd43bc --- /dev/null +++ b/contrib/impcap/ipx_parser.c @@ -0,0 +1,97 @@ +/* ipx_parser.c + * + * This file contains functions to parse IPX (Novell) headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +struct __attribute__ ((__packed__)) ipx_header_s { + uint16_t chksum; + uint16_t pktLen; + uint8_t transCtrl; + uint8_t type; + uint32_t dstNet; + uint8_t dstNode[6]; + uint16_t dstSocket; + uint32_t srcNet; + uint8_t srcNode[6]; + uint16_t srcSocket; +}; +#pragma GCC diagnostic pop + +typedef struct ipx_header_s ipx_header_t; + +/* + * This function parses the bytes in the received packet to extract IPX metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the IPX header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where IPX metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *ipx_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + + DBGPRINTF("entered ipx_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 30) { /* too short for IPX header */ + DBGPRINTF("IPX packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0) + } + + char ipxSrcNode[20], ipxDstNode[20]; + ipx_header_t *ipx_header = (ipx_header_t *)packet; + + snprintf(ipxDstNode, sizeof(ipxDstNode), "%02x:%02x:%02x:%02x:%02x:%02x", ipx_header->dstNode[0], + ipx_header->dstNode[1], ipx_header->dstNode[2], ipx_header->dstNode[3], ipx_header->dstNode[4], + ipx_header->dstNode[5]); + + snprintf(ipxSrcNode, sizeof(ipxSrcNode), "%02x:%02x:%02x:%02x:%02x:%02x", ipx_header->srcNode[0], + ipx_header->srcNode[1], ipx_header->srcNode[2], ipx_header->srcNode[3], ipx_header->srcNode[4], + ipx_header->srcNode[5]); + + json_object_object_add(jparent, "IPX_transCtrl", json_object_new_int(ipx_header->transCtrl)); + json_object_object_add(jparent, "IPX_type", json_object_new_int(ipx_header->type)); + json_object_object_add(jparent, "IPX_dest_net", json_object_new_int(ntohl(ipx_header->dstNet))); + json_object_object_add(jparent, "IPX_src_net", json_object_new_int(ntohl(ipx_header->srcNet))); + json_object_object_add(jparent, "IPX_dest_node", json_object_new_string(ipxDstNode)); + json_object_object_add(jparent, "IPX_src_node", json_object_new_string(ipxSrcNode)); + json_object_object_add(jparent, "IPX_dest_socket", json_object_new_int(ntohs(ipx_header->dstSocket))); + json_object_object_add(jparent, "IPX_src_socket", json_object_new_int(ntohs(ipx_header->srcSocket))); + + RETURN_DATA_AFTER(30) +} diff --git a/contrib/impcap/llc_parser.c b/contrib/impcap/llc_parser.c new file mode 100644 index 0000000..fca4568 --- /dev/null +++ b/contrib/impcap/llc_parser.c @@ -0,0 +1,109 @@ +/* llc_parser.c + * + * This file contains functions to parse llc headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +/* + * This function parses the bytes in the received packet to extract LLC metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the LLC header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where LLC metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *llc_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("entered llc_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 3) { /* too short for llc header */ + DBGPRINTF("LLC packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0) + } + + uint8_t dsapField, dsap, ssapField, ssap; + uint16_t ctrl; + uint8_t headerLen; + + dsapField = (uint8_t)packet[0]; + ssapField = (uint8_t)packet[1]; + DBGPRINTF("dsapField : %02X\n", dsapField); + DBGPRINTF("ssapField : %02X\n", ssapField); + + if (dsapField == 0xff && ssapField == 0xff) { + /* this is an IPX packet, without LLC */ + return ipx_parse(packet, pktSize, jparent); + } + + if ((packet[2] & 0x03) == 3) { + /* U frame: LLC control is 8 bits */ + ctrl = (uint8_t)packet[2]; + headerLen = 3; + } else { + /* I and S data frames: LLC control is 16 bits */ + ctrl = ntohs((uint16_t)packet[2]); + headerLen = 4; + } + + /* don't take last bit into account */ + dsap = dsapField & 0xfe; + ssap = ssapField & 0xfe; + + json_object_object_add(jparent, "LLC_dsap", json_object_new_int(dsap)); + json_object_object_add(jparent, "LLC_ssap", json_object_new_int(ssap)); + json_object_object_add(jparent, "LLC_ctrl", json_object_new_int(ctrl)); + + if (dsap == 0xaa && ssap == 0xaa && ctrl == 0x03) { + /* SNAP header */ + uint32_t orgCode = packet[headerLen] << 16 | + packet[headerLen + 1] << 8 | + packet[headerLen + 2]; + uint16_t ethType = packet[headerLen + 3] << 8 | + packet[headerLen + 4]; + json_object_object_add(jparent, "SNAP_oui", json_object_new_int(orgCode)); + json_object_object_add(jparent, "SNAP_ethType", json_object_new_int(ethType)); + return eth_proto_parse(ethType, packet + headerLen, pktSize - headerLen, jparent); + } + if (dsap == 0x06 && ssap == 0x06 && ctrl == 0x03) { + /* IPv4 header */ + return ipv4_parse(packet + headerLen, pktSize - headerLen, jparent); + } + if (dsap == 0xe0 && ssap == 0xe0 && ctrl == 0x03) { + /* IPX packet with LLC */ + return ipx_parse(packet + headerLen, pktSize - headerLen, jparent); + } + + RETURN_DATA_AFTER(headerLen) +} diff --git a/contrib/impcap/parsers.h b/contrib/impcap/parsers.h new file mode 100644 index 0000000..d2e71d4 --- /dev/null +++ b/contrib/impcap/parsers.h @@ -0,0 +1,189 @@ +/* parser.h + * + * This file contains the prototypes of all the parsers available within impcap. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <stdarg.h> +#include <ctype.h> +#include <pcap.h> + +#include "rsyslog.h" +#include "msg.h" +#include "dirty.h" + +#ifdef __FreeBSD__ +#include <sys/socket.h> +#else + +#include <netinet/ether.h> + +#endif + +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#include <netinet/ip_icmp.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <net/ethernet.h> +#include <arpa/inet.h> + +#ifndef INCLUDED_PARSER_H +#define INCLUDED_PARSER_H 1 + +/* data return structure */ +struct data_ret_s { + size_t size; + char *pData; +}; +typedef struct data_ret_s data_ret_t; + +#define RETURN_DATA_AFTER(x) data_ret_t *retData = malloc(sizeof(data_ret_t)); \ + if(pktSize > x) { \ + retData->size = pktSize - x; \ + retData->pData = (char *)packet + x; \ + } \ + else { \ + retData->size = 0; \ + retData->pData = NULL; \ + } \ + return retData; \ + +/* --- handlers prototypes --- */ +void packet_parse(uchar *arg, const struct pcap_pkthdr *pkthdr, const uchar *packet); + +data_ret_t *eth_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *llc_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *ipx_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *ipv4_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *icmp_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *tcp_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *udp_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *ipv6_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *arp_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *rarp_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *ah_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *esp_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *smb_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *ftp_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *http_parse(const uchar *packet, int pktSize, struct json_object *jparent); + +data_ret_t *dns_parse(const uchar *packet, int pktSize, struct json_object *jparent); + + +// inline function definitions +static inline data_ret_t *dont_parse( + const uchar *packet, + int pktSize, + __attribute__((unused)) struct json_object *jparent); + +static inline data_ret_t *eth_proto_parse( + uint16_t ethProto, + const uchar *packet, + int pktSize, + struct json_object *jparent); + +static inline data_ret_t *ip_proto_parse( + uint16_t ipProto, + const uchar *packet, + int pktSize, + struct json_object *jparent); + +/* + * Mock function to do no parsing when protocol is not a valid number +*/ +static inline data_ret_t *dont_parse( + const uchar *packet, + int pktSize, + __attribute__((unused)) struct json_object *jparent) +{ + DBGPRINTF("protocol not handled\n"); + RETURN_DATA_AFTER(0) +} + +// proto code handlers +static inline data_ret_t *eth_proto_parse( + uint16_t ethProto, + const uchar *packet, + int pktSize, + struct json_object *jparent) +{ + switch(ethProto) { + case ETHERTYPE_IP: + return ipv4_parse(packet, pktSize, jparent); + case ETHERTYPE_IPV6: + return ipv6_parse(packet, pktSize, jparent); + case ETHERTYPE_ARP: + return arp_parse(packet, pktSize, jparent); + case ETHERTYPE_REVARP: + return rarp_parse(packet, pktSize, jparent); + case ETHERTYPE_IPX: + return ipx_parse(packet, pktSize, jparent); + default: + return dont_parse(packet, pktSize, jparent); + } +} + +static inline data_ret_t *ip_proto_parse( + uint16_t ipProto, + const uchar *packet, + int pktSize, + struct json_object *jparent) +{ + switch(ipProto) { + case IPPROTO_TCP: + return tcp_parse(packet, pktSize, jparent); + case IPPROTO_UDP: + return udp_parse(packet, pktSize, jparent); + case IPPROTO_ICMP: + return icmp_parse(packet, pktSize, jparent); + default: + return dont_parse(packet, pktSize, jparent); + } +} + +#endif /* INCLUDED_PARSER_H */ diff --git a/contrib/impcap/smb_parser.c b/contrib/impcap/smb_parser.c new file mode 100644 index 0000000..e673cd3 --- /dev/null +++ b/contrib/impcap/smb_parser.c @@ -0,0 +1,145 @@ +/* smb_parser.c + * + * This file contains functions to parse SMB (version 2 and 3) headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +/* SMB2 opCodes */ +#define SMB2_NEGOTIATE 0x00 +#define SMB2_SESSIONSET 0x01 +#define SMB2_SESSIONLOGOFF 0x02 +#define SMB2_TREECONNECT 0x03 +#define SMB2_TREEDISCONNECT 0x04 +#define SMB2_CREATE 0x05 +#define SMB2_CLOSE 0x06 +#define SMB2_FLUSH 0x07 +#define SMB2_READ 0x08 +#define SMB2_WRITE 0x09 +#define SMB2_LOCK 0x0a +#define SMB2_IOCTL 0x0b +#define SMB2_CANCEL 0x0c +#define SMB2_KEEPALIVE 0x0d +#define SMB2_FIND 0x0e +#define SMB2_NOTIFY 0x0f +#define SMB2_GETINFO 0x10 +#define SMB2_SETINFO 0x11 +#define SMB2_BREAK 0x12 + +struct smb_header_s { + uint32_t version; + uint16_t headerLength; + uint16_t padding1; + uint32_t ntStatus; + uint16_t opCode; + uint16_t padding2; + uint32_t flags; + uint32_t chainOffset; + uint32_t comSeqNumber[2]; + uint32_t processID; + uint32_t treeID; + uint32_t userID[2]; + uint32_t signature[4]; +}; + +typedef struct smb_header_s smb_header_t; + +static char flagCodes[5] = "RPCS"; + +/* + * This function parses the bytes in the received packet to extract SMB2 metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the beginning of the header will be checked by the function + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where SMB2 metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *smb_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("smb_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + int pktSizeCpy = pktSize; + const uchar *packetCpy = packet; + + while (pktSizeCpy > 0) { + /* don't check packetCpy[0] to include SMB version byte at the beginning */ + if (packetCpy[1] == 'S') { + if (packetCpy[2] == 'M') { + if (packetCpy[3] == 'B') { + break; + } + } + } + packetCpy++, pktSizeCpy--; + } + + if ((int)pktSizeCpy < 64) { + DBGPRINTF("SMB packet too small : %d\n", pktSizeCpy); + RETURN_DATA_AFTER(0) + } + + /* Union to prevent cast from uchar to smb_header_t */ + union { + const uchar *pck; + smb_header_t *hdr; + } smb_header_to_char; + + smb_header_to_char.pck = packetCpy; + smb_header_t *smb_header = smb_header_to_char.hdr; + + char flags[5] = {0}; + uint64_t seqNum, userID; + uint8_t version; + + version = (smb_header->version == 0xFF) ? 1 : 2; + seqNum = smb_header->comSeqNumber[0] | smb_header->comSeqNumber[1] << 16; + userID = smb_header->userID[0] | smb_header->userID[1] << 16; + + uint8_t i, pos = 0; + for (i = 0; i < 4; ++i) { + if (smb_header->flags & (0x01 << i)) + flags[pos++] = flagCodes[i]; + } + + json_object_object_add(jparent, "SMB_version", json_object_new_int(version)); + json_object_object_add(jparent, "SMB_NTstatus", json_object_new_int64(smb_header->ntStatus)); + json_object_object_add(jparent, "SMB_operation", json_object_new_int(smb_header->opCode)); + json_object_object_add(jparent, "SMB_flags", json_object_new_string(flags)); + json_object_object_add(jparent, "SMB_seqNumber", json_object_new_int64(seqNum)); + json_object_object_add(jparent, "SMB_processID", json_object_new_int64(smb_header->processID)); + json_object_object_add(jparent, "SMB_treeID", json_object_new_int64(smb_header->treeID)); + json_object_object_add(jparent, "SMB_userID", json_object_new_int64(userID)); + + RETURN_DATA_AFTER(0) +} diff --git a/contrib/impcap/tcp_parser.c b/contrib/impcap/tcp_parser.c new file mode 100644 index 0000000..b96c1f3 --- /dev/null +++ b/contrib/impcap/tcp_parser.c @@ -0,0 +1,121 @@ +/* tcp_parser.c + * + * This file contains functions to parse TCP headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +#define SMB_PORT 445 +#define HTTP_PORT 80 +#define HTTP_PORT_ALT 8080 +#define FTP_PORT 21 +#define FTP_PORT_DATA 20 + +struct tcp_header_s { + uint16_t srcPort; + uint16_t dstPort; + uint32_t seq; + uint32_t ack; + uint8_t dor; + uint8_t flags; + uint16_t windowSize; + uint16_t checksum; + uint16_t urgPointer; + uint8_t options[]; +}; + +typedef struct tcp_header_s tcp_header_t; + +static char flagCodes[10] = "FSRPAUECN"; + +/* + * This function parses the bytes in the received packet to extract TCP metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the TCP header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where TCP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *tcp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("tcp_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 20) { + DBGPRINTF("TCP packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0) + } + + /* Union to prevent cast from uchar to tcp_header_t */ + union { + const uchar *pck; + tcp_header_t *hdr; + } tcp_header_to_char; + + tcp_header_to_char.pck = packet; + tcp_header_t *tcp_header = tcp_header_to_char.hdr; + + uint8_t i, pos = 0; + char flags[10] = {0}; + + for (i = 0; i < 8; ++i) { + if (tcp_header->flags & (0x01 << i)) + flags[pos++] = flagCodes[i]; + } + if (tcp_header->dor & 0x01) + flags[pos++] = flagCodes[9]; + + uint16_t srcPort = ntohs(tcp_header->srcPort); + uint16_t dstPort = ntohs(tcp_header->dstPort); + + uint8_t headerLength = (tcp_header->dor & 0xF0) >> 2; //>>4 to offset but <<2 to get offset as bytes + + json_object_object_add(jparent, "net_src_port", json_object_new_int(srcPort)); + json_object_object_add(jparent, "net_dst_port", json_object_new_int(dstPort)); + json_object_object_add(jparent, "TCP_seq_number", json_object_new_int64(ntohl(tcp_header->seq))); + json_object_object_add(jparent, "TCP_ack_number", json_object_new_int64(ntohl(tcp_header->ack))); + json_object_object_add(jparent, "net_flags", json_object_new_string(flags)); + + if (srcPort == SMB_PORT || dstPort == SMB_PORT) { + return smb_parse(packet + headerLength, pktSize - headerLength, jparent); + } + if (srcPort == FTP_PORT || dstPort == FTP_PORT || srcPort == FTP_PORT_DATA || dstPort == FTP_PORT_DATA) { + return ftp_parse(packet + headerLength, pktSize - headerLength, jparent); + } + if (srcPort == HTTP_PORT || dstPort == HTTP_PORT || + srcPort == HTTP_PORT_ALT || dstPort == HTTP_PORT_ALT) { + return http_parse(packet + headerLength, pktSize - headerLength, jparent); + } + DBGPRINTF("tcp return after header length (%u)\n", headerLength); + RETURN_DATA_AFTER(headerLength) +} diff --git a/contrib/impcap/udp_parser.c b/contrib/impcap/udp_parser.c new file mode 100644 index 0000000..a9b7dca --- /dev/null +++ b/contrib/impcap/udp_parser.c @@ -0,0 +1,90 @@ +/* udp_parser.c + * + * This file contains functions to parse UDP headers. + * + * File begun on 2018-11-13 + * + * Created by: + * - Théo Bertin (theo.bertin@advens.fr) + * + * With: + * - François Bernard (francois.bernard@isen.yncrea.fr) + * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "parsers.h" + +#define DNS_PORT 53 + +struct udp_header_s { + uint16_t srcPort; + uint16_t dstPort; + uint16_t totalLength; + uint16_t checksum; +}; + +typedef struct udp_header_s udp_header_t; + +/* + * This function parses the bytes in the received packet to extract UDP metadata. + * + * its parameters are: + * - a pointer on the list of bytes representing the packet + * the first byte must be the beginning of the UDP header + * - the size of the list passed as first parameter + * - a pointer on a json_object, containing all the metadata recovered so far + * this is also where UDP metadata will be added + * + * This function returns a structure containing the data unprocessed by this parser + * or the ones after (as a list of bytes), and the length of this data. +*/ +data_ret_t *udp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { + DBGPRINTF("udp_parse\n"); + DBGPRINTF("packet size %d\n", pktSize); + + if (pktSize < 8) { + DBGPRINTF("UDP packet too small : %d\n", pktSize); + RETURN_DATA_AFTER(0) + } + + /* Union to prevent cast from uchar to udp_header_t */ + union { + const uchar *pck; + udp_header_t *hdr; + } udp_header_to_char; + + udp_header_to_char.pck = packet; + udp_header_t *udp_header = udp_header_to_char.hdr; + + // Prevent endianness issue + unsigned short int src_port = ntohs(udp_header->srcPort); + unsigned short int dst_port = ntohs(udp_header->dstPort); + + json_object_object_add(jparent, "net_src_port", json_object_new_int(src_port)); + json_object_object_add(jparent, "net_dst_port", json_object_new_int(dst_port)); + json_object_object_add(jparent, "UDP_Length", json_object_new_int(ntohs(udp_header->totalLength))); + json_object_object_add(jparent, "UDP_Checksum", json_object_new_int(ntohs(udp_header->checksum))); + + if (src_port == DNS_PORT || dst_port == DNS_PORT) { + return dns_parse(packet + sizeof(udp_header_t), pktSize - sizeof(udp_header_t), jparent); + } + + RETURN_DATA_AFTER(8) +} diff --git a/contrib/improg/Makefile.am b/contrib/improg/Makefile.am new file mode 100644 index 0000000..3309098 --- /dev/null +++ b/contrib/improg/Makefile.am @@ -0,0 +1,11 @@ +pkglib_LTLIBRARIES = improg.la + +improg_la_SOURCES = improg.c +improg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +improg_la_LDFLAGS = -module -avoid-version +improg_la_LIBADD = + +if ENABLE_LIBLOGGING_STDLOG +improg_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) +improg_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) +endif diff --git a/contrib/improg/Makefile.in b/contrib/improg/Makefile.in new file mode 100644 index 0000000..bf69352 --- /dev/null +++ b/contrib/improg/Makefile.in @@ -0,0 +1,799 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_1 = $(LIBLOGGING_STDLOG_CFLAGS) +@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_2 = $(LIBLOGGING_STDLOG_LIBS) +subdir = contrib/improg +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +improg_la_DEPENDENCIES = +am_improg_la_OBJECTS = improg_la-improg.lo +improg_la_OBJECTS = $(am_improg_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +improg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(improg_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/improg_la-improg.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(improg_la_SOURCES) +DIST_SOURCES = $(improg_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = improg.la +improg_la_SOURCES = improg.c +improg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) \ + $(am__append_1) +improg_la_LDFLAGS = -module -avoid-version $(am__append_2) +improg_la_LIBADD = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/improg/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/improg/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +improg.la: $(improg_la_OBJECTS) $(improg_la_DEPENDENCIES) $(EXTRA_improg_la_DEPENDENCIES) + $(AM_V_CCLD)$(improg_la_LINK) -rpath $(pkglibdir) $(improg_la_OBJECTS) $(improg_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improg_la-improg.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +improg_la-improg.lo: improg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(improg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT improg_la-improg.lo -MD -MP -MF $(DEPDIR)/improg_la-improg.Tpo -c -o improg_la-improg.lo `test -f 'improg.c' || echo '$(srcdir)/'`improg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/improg_la-improg.Tpo $(DEPDIR)/improg_la-improg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='improg.c' object='improg_la-improg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(improg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o improg_la-improg.lo `test -f 'improg.c' || echo '$(srcdir)/'`improg.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/improg_la-improg.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/improg_la-improg.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/improg/improg.c b/contrib/improg/improg.c new file mode 100644 index 0000000..d525ddd --- /dev/null +++ b/contrib/improg/improg.c @@ -0,0 +1,722 @@ +/* improg.c + * This input plugin enables rsyslog to execute a program and + * receive from it the message stream as standard input. + * One message per line with a maximum size + * + * NOTE: read comments in module-template.h for more specifics! + * + * File begun on 2009-04-01 by RGerhards + * File copied and adjust from improg.c on 2019-02-07 by Ph. Duveau + * + * Copyright 2009-2018 Adiscon GmbH. + * + * This file is contribution of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include <stdio.h> +#include <syslog.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <pthread.h> +#include <poll.h> + +/* Very strange error on solaris 11 LOG_CRON already defined here. + * It is redefined in rsyslog.h + * The error also appeared with module omprog but the warning is + * accepted without generated an error + */ +#ifdef LOG_CRON +#undef LOG_CRON +#endif + +#include "rsyslog.h" +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "unicode-helper.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "glbl.h" +#include "prop.h" +#include "ruleset.h" +#include "ratelimit.h" +#include "stringbuf.h" + +MODULE_TYPE_INPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("improg") + +struct instanceConf_s { + uchar *pszBinary; /* name of external program to call */ + char **aParams; /* optional parameters to pass to external program */ + int iParams; /* holds the count of parameters if set */ + uchar *pszTag; + size_t lenTag; + int iFacility; + int iSeverity; + int bConfirmMessages; /* does the program provide feedback via stdout? */ + int bSignalOnClose; /* should send SIGTERM to program before closing pipe? */ + long lCloseTimeout; /* how long to wait for program to terminate after closing pipe (ms) */ + int bKillUnresponsive; /* should send SIGKILL if closeTimeout is reached? */ + cstr_t *ppCStr; + int bIsRunning; /* is program currently running? 0-no, 1-yes */ + pid_t pid; /* pid of currently running child process */ + int fdPipeToChild; /* fd for sending data to the program */ + int fdPipeFromChild; /* fd for receiving messages from the program, or -1 */ + uchar *pszBindRuleset; + ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ + ratelimit_t *ratelimiter; + struct instanceConf_s *next; + struct instanceConf_s *prev; +}; + +/* config variables */ +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + +}; + +/* internal structures + */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) + +static prop_t *pInputName = NULL; + +#define NO_HUP_FORWARD -1 /* indicates that HUP should NOT be forwarded */ +#define DEFAULT_CONFIRM_TIMEOUT_MS 10000 +#define DEFAULT_CLOSE_TIMEOUT_MS 5000 +#define RESPONSE_LINE_BUFFER_SIZE 4096 +#define OUTPUT_CAPTURE_BUFFER_SIZE 4096 +#define MAX_FD_TO_CLOSE 65535 + +static instanceConf_t *confRoot = NULL; +static fd_set rfds; +static int nfds = 0; + +extern char **environ; /* POSIX environment ptr, by std not in a header... (see man 7 environ) */ + +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *pInst) +{ + LogError(0, NO_ERRCODE, "improg: ruleset '%s' for binary %s not found - " + "using default ruleset instead", pInst->pszBindRuleset, + pInst->pszBinary); +} + +#include "im-helper.h" /* must be included AFTER the type definitions! */ + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr inppdescr[] = { + { "binary", eCmdHdlrString, CNFPARAM_REQUIRED }, + { "tag", eCmdHdlrString, CNFPARAM_REQUIRED }, + { "severity", eCmdHdlrSeverity, 0 }, + { "facility", eCmdHdlrFacility, 0 }, + { "ruleset", eCmdHdlrString, 0 }, + { "confirmmessages", eCmdHdlrBinary, 0 }, + { "signalonclose", eCmdHdlrBinary, 0 }, + { "closetimeout", eCmdHdlrInt, 0 }, + { "killunresponsive", eCmdHdlrBinary, 0 } +}; +static struct cnfparamblk inppblk = + { CNFPARAMBLK_VERSION, + sizeof(inppdescr)/sizeof(struct cnfparamdescr), + inppdescr + }; + +/* execute the external program (must be called in child context after fork). + */ +static __attribute__((noreturn)) void execBinary(const instanceConf_t *pInst, int pipeToParent, int pipeFromParent) +{ + int maxFd, fd, sigNum; + struct sigaction sigAct; + sigset_t sigSet; + char errStr[1024]; + + if(dup2(pipeToParent, STDOUT_FILENO) == -1) { + goto failed; + } + + if(pipeFromParent != -1) { + if(dup2(pipeFromParent, STDIN_FILENO) == -1) { + goto failed; + } + } + + /* close the file handles the child process doesn't need (all above STDERR). + * The following way is simple and portable, though not perfect. + * See https://stackoverflow.com/a/918469 for alternatives. + */ + maxFd = sysconf(_SC_OPEN_MAX); + if(maxFd < 0 || maxFd > MAX_FD_TO_CLOSE) { + maxFd = MAX_FD_TO_CLOSE; + } + # ifdef VALGRIND + else { + maxFd -= 10; + } + # endif + for(fd = STDERR_FILENO + 1 ; fd <= maxFd ; ++fd) { + close(fd); + } + + /* reset signal handlers to default */ + memset(&sigAct, 0, sizeof(sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = SIG_DFL; + for(sigNum = 1 ; sigNum < NSIG ; ++sigNum) { + sigaction(sigNum, &sigAct, NULL); + } + + /* we need to block SIGINT, otherwise our program is cancelled when we are + * stopped in debug mode. + */ + sigAct.sa_handler = SIG_IGN; + sigaction(SIGINT, &sigAct, NULL); + sigemptyset(&sigSet); + sigprocmask(SIG_SETMASK, &sigSet, NULL); + + alarm(0); + + /* finally exec program */ + execve((char*)pInst->pszBinary, pInst->aParams, environ); + +failed: + /* an error occurred: log it and exit the child process. We use the + * 'syslog' system call to log the error (we cannot use LogMsg/LogError, + * since these functions add directly to the rsyslog input queue). + */ + rs_strerror_r(errno, errStr, sizeof(errStr)); + DBGPRINTF("improg: failed to execute program '%s': %s\n", + pInst->pszBinary, errStr); + openlog("rsyslogd", 0, LOG_SYSLOG); + syslog(LOG_ERR, "improg: failed to execute program '%s': %s\n", + pInst->pszBinary, errStr); + /* let's print the error to stderr for test bench purposes */ + fprintf(stderr, "improg: failed to execute program '%s': %s\n", + pInst->pszBinary, errStr); + exit(1); +} + +/* creates a pipe and starts program, uses pipe as stdin for program. + * rgerhards, 2009-04-01 + */ +static rsRetVal openPipe(instanceConf_t *pInst) +{ + int pipeFromChild[2] = { -1, -1 }; + int pipeToChild[2] = { -1, -1 }; + pid_t cpid; + DEFiRet; + + /* if the 'confirmMessages' setting is enabled, open a pipe to send + message confirmations to the program */ + if(pInst->bConfirmMessages && pipe(pipeToChild) == -1) { + ABORT_FINALIZE(RS_RET_ERR_CREAT_PIPE); + } + + /* open a pipe to receive messages to the program */ + if(pipe(pipeFromChild) == -1) { + ABORT_FINALIZE(RS_RET_ERR_CREAT_PIPE); + } + + DBGPRINTF("improg: executing program '%s' with '%d' parameters\n", + pInst->pszBinary, pInst->iParams); + + cpid = fork(); + if(cpid == -1) { + ABORT_FINALIZE(RS_RET_ERR_FORK); + } + + if(cpid == 0) { /* we are now the child process: execute the program */ + /* close the pipe ends that the child doesn't need */ + close(pipeFromChild[0]); + if(pipeToChild[1] != -1) { + close(pipeToChild[1]); + } + + execBinary(pInst, pipeFromChild[1], pipeToChild[0]); + /* NO CODE HERE - WILL NEVER BE REACHED! */ + } + + DBGPRINTF("improg: child has pid %ld\n", (long int) cpid); + + /* close the pipe ends that the parent doesn't need */ + close(pipeFromChild[1]); + if(pipeToChild[0] != -1) { + close(pipeToChild[0]); + } + + pInst->fdPipeToChild = pipeToChild[1]; /* we'll send messages confirmations to the program via this fd */ + pInst->fdPipeFromChild = pipeFromChild[0]; /* we'll receive message via this fd */ + + FD_SET(pInst->fdPipeFromChild, &rfds); /* manage select read fd set */ + nfds = (nfds > pInst->fdPipeFromChild) ? nfds : pInst->fdPipeFromChild+1; + + pInst->pid = cpid; + pInst->bIsRunning = 1; + +finalize_it: + if(iRet != RS_RET_OK) { + if(pipeFromChild[0] != -1) { + close(pipeFromChild[0]); + close(pipeFromChild[1]); + } + if(pipeToChild[0] != -1) { + close(pipeToChild[0]); + close(pipeToChild[1]); + } + } + RETiRet; +} + +static void waitForChild(instanceConf_t *pInst) +{ + int status; + int ret; + long counter; + + counter = pInst->lCloseTimeout / 10; + while ((ret = waitpid(pInst->pid, &status, WNOHANG)) == 0 && counter > 0) { + srSleep(0, 10000); /* 0 seconds, 10 milliseconds */ + --counter; + } + + if (ret == 0) { /* timeout reached */ + if (!pInst->bKillUnresponsive) { + LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: program '%s' (pid %ld) did not terminate " + "within timeout (%ld ms); ignoring it", pInst->pszBinary, (long int)pInst->pid, + pInst->lCloseTimeout); + return; + } + + LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: program '%s' (pid %ld) did not terminate " + "within timeout (%ld ms); killing it", pInst->pszBinary, (long int)pInst->pid, + pInst->lCloseTimeout); + if (kill(pInst->pid, SIGKILL) == -1) { + LogError(errno, RS_RET_SYS_ERR, "improg: could not send SIGKILL to child process"); + return; + } + + ret = waitpid(pInst->pid, &status, 0); + } + + /* waitpid will fail with errno == ECHILD if the child process has already + been reaped by the rsyslogd main loop (see rsyslogd.c) */ + if(ret == pInst->pid) { + glblReportChildProcessExit(runConf, pInst->pszBinary, pInst->pid, status); + } +} + +/* Send SIGTERM to child process if configured to do so, close pipe + * and wait for child to terminate. + */ +static void terminateChild(instanceConf_t *pInst) +{ + if(pInst->bIsRunning) { + + if(pInst->fdPipeFromChild != -1) { + close(pInst->fdPipeFromChild); + FD_CLR(pInst->fdPipeFromChild, &rfds); + pInst->fdPipeFromChild = -1; + + } + + if(pInst->fdPipeToChild != -1) { + close(pInst->fdPipeToChild); + pInst->fdPipeToChild = -1; + } + + /* wait for the child AFTER closing the pipe, so it receives EOF */ + waitForChild(pInst); + + pInst->bIsRunning = 0; + } +} + +static rsRetVal startChild(instanceConf_t *pInst) +{ + DEFiRet; + + if (!pInst->bIsRunning) + + CHKiRet(openPipe(pInst)); + +finalize_it: + if(iRet != RS_RET_OK && pInst->bIsRunning) { + /* if initialization has failed, terminate program */ + terminateChild(pInst); + } + RETiRet; +} + +static rsRetVal enqLine(instanceConf_t *const __restrict__ pInst) +{ + DEFiRet; + smsg_t *pMsg; + + if(cstrLen(pInst->ppCStr) == 0) { + /* we do not process empty lines */ + FINALIZE; + } + + CHKiRet(msgConstruct(&pMsg)); + + MsgSetMSGoffs(pMsg, 0); + MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); + MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY); + MsgSetInputName(pMsg, pInputName); + MsgSetAPPNAME(pMsg, (const char*)pInst->pszTag); + MsgSetTAG(pMsg, pInst->pszTag, pInst->lenTag); + msgSetPRI(pMsg, pInst->iFacility | pInst->iSeverity); + MsgSetRawMsg(pMsg, (const char*)rsCStrGetBufBeg(pInst->ppCStr), cstrLen(pInst->ppCStr)); + MsgSetRuleset(pMsg, pInst->pBindRuleset); + + ratelimitAddMsg(pInst->ratelimiter, NULL, pMsg); +finalize_it: + RETiRet; +} + +/* read line(s) from the external program and sent them when they are complete */ +static rsRetVal readChild(instanceConf_t *const pInst){ + char c; + int retval; + + while ((retval = read(pInst->fdPipeFromChild, &c, 1)) == 1) { + if (c=='\n'){ + enqLine(pInst); + /* if confirm required then send an ACK to the program */ + if (pInst->bConfirmMessages) { + if (write(pInst->fdPipeToChild,"ACK\n",sizeof("ACK\n")-1) <= 0) + LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: pipe to child seems to be closed."); + } + rsCStrTruncate(pInst->ppCStr, rsCStrLen(pInst->ppCStr)); + } else { + cstrAppendChar(pInst->ppCStr, c); + } + } + return (retval == 0) ? RS_RET_OK : RS_RET_IO_ERROR; +} + +/* create input instance, set default parameters, and + * add it to the list of instances. + */ +static rsRetVal ATTR_NONNULL(1) createInstance(instanceConf_t **const ppInst) +{ + instanceConf_t *pInst; + DEFiRet; + CHKmalloc(pInst = malloc(sizeof(instanceConf_t))); + pInst->next = NULL; + pInst->pszBindRuleset = NULL; + pInst->pBindRuleset = NULL; + pInst->ratelimiter = NULL; + pInst->iSeverity = 5; + pInst->iFacility = 128; + + pInst->pszTag = NULL; + pInst->lenTag = 0; + + pInst->bIsRunning = 0; + pInst->pid = -1; + pInst->fdPipeToChild = -1; + pInst->fdPipeFromChild = -1; + + pInst->pszBinary = NULL; + pInst->aParams = NULL; + pInst->iParams = 0; + + pInst->bConfirmMessages = 1; + pInst->bSignalOnClose = 0; + pInst->lCloseTimeout = 200; + pInst->bKillUnresponsive = 1; + + *ppInst = pInst; +finalize_it: + RETiRet; +} + +/* This adds a new listener object to the bottom of the list, but + * it does NOT initialize any data members except for the list + * pointers themselves. + */ +static rsRetVal ATTR_NONNULL() lstnAdd(instanceConf_t *pInst) +{ + DEFiRet; + CHKiRet(ratelimitNew(&pInst->ratelimiter, "improg", (char*)pInst->pszBinary)); + + /* insert it at the begin of the list */ + pInst->prev = NULL; + pInst->next = confRoot; + + if (confRoot != NULL) + confRoot->prev = pInst; + + confRoot = pInst; + +finalize_it: + RETiRet; +} + +/* delete a listener object */ +static void ATTR_NONNULL(1) lstnFree(instanceConf_t *pInst) +{ + DBGPRINTF("lstnFree called for %s\n", pInst->pszBinary); + if (pInst->ratelimiter != NULL) + ratelimitDestruct(pInst->ratelimiter); + if(pInst->pszBinary != NULL) + free(pInst->pszBinary); + if (pInst->pszTag) + free(pInst->pszTag); + if (pInst->pszBindRuleset != NULL) + free(pInst->pszBindRuleset); + if (pInst->aParams) { + int i; + for (i = 0;pInst->aParams[i]; i++) + free(pInst->aParams[i]); + free(pInst->aParams); + } + if (pInst->ppCStr) + rsCStrDestruct(&pInst->ppCStr); + free(pInst); +} + +/* read */ +BEGINnewInpInst + struct cnfparamvals *pvals; + instanceConf_t *pInst = NULL; + int i; +CODESTARTnewInpInst + DBGPRINTF("newInpInst (improg)\n"); + + pvals = nvlstGetParams(lst, &inppblk, NULL); + if(pvals == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + DBGPRINTF("input param blk in improg:\n"); + cnfparamsPrint(&inppblk, pvals); + } + + CHKiRet(createInstance(&pInst)); + + for(i = 0 ; i < inppblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(inppblk.descr[i].name, "binary")) { + CHKiRet(split_binary_parameters(&pInst->pszBinary, &pInst->aParams, &pInst->iParams, + pvals[i].val.d.estr)); + } else if(!strcmp(inppblk.descr[i].name, "tag")) { + pInst->pszTag = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + pInst->lenTag = es_strlen(pvals[i].val.d.estr); + } else if(!strcmp(inppblk.descr[i].name, "ruleset")) { + pInst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "severity")) { + pInst->iSeverity = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "facility")) { + pInst->iFacility = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "confirmmessages")) { + pInst->bConfirmMessages = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "signalonclose")) { + pInst->bSignalOnClose = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "closetimeout")) { + pInst->lCloseTimeout = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "killunresponsive")) { + pInst->bKillUnresponsive = pvals[i].val.d.n; + } else { + DBGPRINTF("program error, non-handled " + "param '%s'\n", inppblk.descr[i].name); + } + } + if(pInst->pszBinary == NULL) { + LogError(0, RS_RET_FILE_NOT_SPECIFIED, + "ulogbase is not configured - no input will be gathered"); + ABORT_FINALIZE(RS_RET_FILE_NOT_SPECIFIED); + } + + CHKiRet(cstrConstruct(&pInst->ppCStr)); + + if ((iRet = lstnAdd(pInst)) != RS_RET_OK) { + ABORT_FINALIZE(iRet); + } + +finalize_it: +CODE_STD_FINALIZERnewInpInst + if (pInst && iRet != RS_RET_OK) + lstnFree(pInst); + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + +BEGINwillRun +CODESTARTwillRun + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("improg"), sizeof("improg") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); +finalize_it: +ENDwillRun + +BEGINrunInput + struct timeval tv; + int retval; + instanceConf_t *pInst; +CODESTARTrunInput + FD_ZERO(&rfds); + + for(pInst = confRoot ; pInst != NULL ; pInst = pInst->next) { + startChild(pInst); + } + + for(pInst = confRoot ; pInst != NULL ; pInst = pInst->next) { + if (pInst->bIsRunning && pInst->fdPipeToChild > 0){ + if (write(pInst->fdPipeToChild, "START\n", sizeof("START\n")-1) <= 0) + LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: pipe to child seems to be closed."); + DBGPRINTF("Sending START to %s\n", pInst->pszBinary); + } + } + + /* main module loop */ + tv.tv_usec = 1000; + while (glbl.GetGlobalInputTermState() == 0) + { + fd_set temp; + memcpy(&temp, &rfds, sizeof(fd_set)); + tv.tv_sec = 0; + + /* wait for external data or 0.1 second */ + retval = select(nfds, &temp, NULL, NULL, &tv); + + /* retval is the number of fd with data to read */ + while (retval>0) { + for (pInst = confRoot; pInst != NULL; pInst = pInst->next) { + if (FD_ISSET(pInst->fdPipeFromChild, &temp)) { + DBGPRINTF("read child %s\n",pInst->pszBinary); + readChild(pInst); + retval--; + } + } + } + tv.tv_usec = 100000; + } + DBGPRINTF("terminating upon request of rsyslog core\n"); +ENDrunInput + +/* This function is called by the framework after runInput() has been terminated. It + * shall free any resources and prepare the module for unload. + * CODEqueryEtryPt_STD_IMOD_QUERIES + */ +BEGINafterRun +CODESTARTafterRun + instanceConf_t *pInst = confRoot, *nextInst; + confRoot = NULL; + + DBGPRINTF("afterRun\n"); + + while(pInst != NULL) { + nextInst = pInst->next; + + if (pInst->bIsRunning) { + if (pInst->bSignalOnClose) { + kill(pInst->pid, SIGTERM); + LogMsg(0, NO_ERRCODE, LOG_INFO, "%s SIGTERM signaled.", pInst->aParams[0]); + } + if (pInst->fdPipeToChild > 0){ + if (write(pInst->fdPipeToChild, "STOP\n", strlen("STOP\n")) <= 0 && + !pInst->bSignalOnClose) + LogMsg(0, NO_ERRCODE, LOG_WARNING, + "improg: pipe to child seems to be closed."); + } + terminateChild(pInst); + } + + lstnFree(pInst); + + pInst = nextInst; + } + + if(pInputName != NULL) + prop.Destruct(&pInputName); +ENDafterRun + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURERepeatedMsgReduction) { + iRet = RS_RET_OK; + } +ENDisCompatibleWithFeature + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +instanceConf_t *pInst; +CODESTARTcheckCnf + for(pInst = confRoot ; pInst != NULL ; pInst = pInst->next) { + std_checkRuleset(pModConf , pInst); + } +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + +BEGINmodExit +CODESTARTmodExit + objRelease(ruleset, CORE_COMPONENT); + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(ruleset, CORE_COMPONENT)); + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); +ENDmodInit diff --git a/contrib/imtuxedoulog/Makefile.am b/contrib/imtuxedoulog/Makefile.am new file mode 100644 index 0000000..1423b85 --- /dev/null +++ b/contrib/imtuxedoulog/Makefile.am @@ -0,0 +1,13 @@ +pkglib_LTLIBRARIES = imtuxedoulog.la + +imtuxedoulog_la_SOURCES = imtuxedoulog.c + +imtuxedoulog_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +imtuxedoulog_la_LDFLAGS = -module -avoid-version +imtuxedoulog_la_LIBADD = + +if OS_AIX +imtuxedoulog_la_CPPFLAGS += -ma +endif + + diff --git a/contrib/imtuxedoulog/Makefile.in b/contrib/imtuxedoulog/Makefile.in new file mode 100644 index 0000000..442dcb5 --- /dev/null +++ b/contrib/imtuxedoulog/Makefile.in @@ -0,0 +1,799 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@OS_AIX_TRUE@am__append_1 = -ma +subdir = contrib/imtuxedoulog +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +imtuxedoulog_la_DEPENDENCIES = +am_imtuxedoulog_la_OBJECTS = imtuxedoulog_la-imtuxedoulog.lo +imtuxedoulog_la_OBJECTS = $(am_imtuxedoulog_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +imtuxedoulog_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(imtuxedoulog_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(imtuxedoulog_la_SOURCES) +DIST_SOURCES = $(imtuxedoulog_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = imtuxedoulog.la +imtuxedoulog_la_SOURCES = imtuxedoulog.c +imtuxedoulog_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) \ + $(RSRT_CFLAGS) $(am__append_1) +imtuxedoulog_la_LDFLAGS = -module -avoid-version +imtuxedoulog_la_LIBADD = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imtuxedoulog/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/imtuxedoulog/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +imtuxedoulog.la: $(imtuxedoulog_la_OBJECTS) $(imtuxedoulog_la_DEPENDENCIES) $(EXTRA_imtuxedoulog_la_DEPENDENCIES) + $(AM_V_CCLD)$(imtuxedoulog_la_LINK) -rpath $(pkglibdir) $(imtuxedoulog_la_OBJECTS) $(imtuxedoulog_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +imtuxedoulog_la-imtuxedoulog.lo: imtuxedoulog.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imtuxedoulog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imtuxedoulog_la-imtuxedoulog.lo -MD -MP -MF $(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Tpo -c -o imtuxedoulog_la-imtuxedoulog.lo `test -f 'imtuxedoulog.c' || echo '$(srcdir)/'`imtuxedoulog.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Tpo $(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imtuxedoulog.c' object='imtuxedoulog_la-imtuxedoulog.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imtuxedoulog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imtuxedoulog_la-imtuxedoulog.lo `test -f 'imtuxedoulog.c' || echo '$(srcdir)/'`imtuxedoulog.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/imtuxedoulog/imtuxedoulog.c b/contrib/imtuxedoulog/imtuxedoulog.c new file mode 100644 index 0000000..ffb863c --- /dev/null +++ b/contrib/imtuxedoulog/imtuxedoulog.c @@ -0,0 +1,860 @@ +/* imtuxedoulog.c + * + * This is the input module for reading Tuxedo ULOG files. The particularity of this file + * is that the timestamp is split between the filename (date) and the log line (time). + * So this module switches on the date base betwwen files to open only the current file. + * The log line is parsed according to the Tuxedo format. The ECID is extracted as a + * structured data attribute. + * + * Work originally begun on 2019-01-11 by Philippe Duveau + * + * This file is contribution of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> /* do NOT remove: will soon be done by the module generation macros */ +#include <sys/types.h> +#include <unistd.h> +#include <glob.h> +#include <poll.h> +#include <fnmatch.h> +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef _AIX +# include <alloca.h> +#endif +#include "rsyslog.h" /* error codes etc... */ +#include "dirty.h" +#include "cfsysline.h" /* access to config file objects */ +#include "module-template.h" /* generic module interface code - very important, read it! */ +#include "srUtils.h" /* some utility functions */ +#include "msg.h" +#include "stream.h" +#include "errmsg.h" +#include "glbl.h" +#include "unicode-helper.h" +#include "prop.h" +#include "stringbuf.h" +#include "ruleset.h" +#include "ratelimit.h" + +struct instanceConf_s { + uchar *pszUlogBaseName; + uchar *pszCurrFName; + struct tm currTm; + uchar *pszTag; + size_t lenTag; + uchar *pszStateFile; + uchar *pszBindRuleset; + int nMultiSub; + int iPersistStateInterval; + int iFacility; + int iSeverity; + strm_t *pStrm; /* its stream (NULL if not assigned) */ + int maxLinesAtOnce; + ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ + ratelimit_t *ratelimiter; + multi_submit_t multiSub; + int nRecords; + struct instanceConf_s *next; + struct instanceConf_s *prev; +}; + +/* config variables */ +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ +}; + +static instanceConf_t *confRoot = NULL; +static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL; /* modConf ptr to use for run process */ + + +MODULE_TYPE_INPUT /* must be present for input modules, do not remove */ +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("imtuxedoulog") + +/* defines */ + +/* Module static data */ +DEF_IMOD_STATIC_DATA /* must be present, starts static data */ +DEFobjCurrIf(glbl) +DEFobjCurrIf(strm) +DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) + +#define NUM_MULTISUB 1024 /* default max number of submits */ +#define DFLT_PollInterval 10 + +int iPollInterval = DFLT_PollInterval; +int iPersistStateInterval = 0; /* how often if state file to be persisted? (default 0->never) */ + +struct syslogTime syslogTz; + +static prop_t *pInputName = NULL; +/* there is only one global inputName for all messages generated by this input */ + +/* module-global parameters */ +/* input instance parameters */ +static struct cnfparamdescr inppdescr[] = { + { "ulogbase", eCmdHdlrString, CNFPARAM_REQUIRED }, + { "tag", eCmdHdlrString, CNFPARAM_REQUIRED }, + { "severity", eCmdHdlrSeverity, 0 }, + { "facility", eCmdHdlrFacility, 0 }, + { "ruleset", eCmdHdlrString, 0 }, + { "maxlinesatonce", eCmdHdlrInt, 0 }, + { "persiststateinterval", eCmdHdlrInt, 0 }, + { "maxsubmitatonce", eCmdHdlrInt, 0 } +}; +static struct cnfparamblk inppblk = + { CNFPARAMBLK_VERSION, + sizeof(inppdescr)/sizeof(struct cnfparamdescr), + inppdescr + }; + +#include "im-helper.h" /* must be included AFTER the type definitions! */ + +static uchar * mkFileNameWithTime(instanceConf_t *in) +{ + uchar out[MAXFNAME]; + struct timeval tp; +#if defined(__hpux) + struct timezone tz; + gettimeofday(&tp, &tz); +#else + gettimeofday(&tp, NULL); +#endif + localtime_r(&tp.tv_sec, &(in->currTm)); + snprintf((char*)out, MAXFNAME, "%s.%02d%02d%02d", (char*)in->pszUlogBaseName, + in->currTm.tm_mon+1, in->currTm.tm_mday, in->currTm.tm_year % 100); + return ustrdup(out); +} + +/* +* Helper function to combine statefile and workdir +*/ +static int getFullStateFileName(uchar* pszstatefile, uchar* pszout, int ilenout) +{ + int lenout; + const uchar* pszworkdir; + + /* Get Raw Workdir, if it is NULL we need to propper handle it */ + pszworkdir = glblGetWorkDirRaw(runModConf->pConf); + + /* Construct file name */ + lenout = snprintf((char*)pszout, ilenout, "%s/%s", + (char*) (pszworkdir == NULL ? "." : (char*) pszworkdir), (char*)pszstatefile); + + /* return out length */ + return lenout; +} + +/* this generates a state file name suitable for the current file. To avoid + * malloc calls, it must be passed a buffer which should be MAXFNAME large. + * Note: the buffer is not necessarily populated ... always ONLY use the + * RETURN VALUE! + */ +static uchar * ATTR_NONNULL(2) getStateFileName(instanceConf_t *const __restrict__ pInst, + uchar *const __restrict__ buf, + size_t lenbuf, + const uchar *pszFileName) +{ + uchar *ret; + + /* Use pszFileName parameter if set */ + pszFileName = pszFileName == NULL ? pInst->pszUlogBaseName : pszFileName; + + DBGPRINTF("getStateFileName for '%s'\n", pszFileName); + if(pInst == NULL || pInst->pszStateFile == NULL) { + lenbuf = snprintf((char*)buf, lenbuf - 1, "imtuxedoulog-state:%s", pszFileName); + buf[lenbuf] = '\0'; /* be on the safe side... */ + uchar *p = buf; + for( ; *p ; ++p) { + if(*p == '/') + *p = '-'; + } + ret = buf; + } else { + ret = pInst->pszStateFile; + } + return ret; +} + +/* this func parses the line according to samples described in README.md + */ +static rsRetVal parseMsg(smsg_t *pMsg, char *rawMsg, size_t msgLen, + instanceConf_t *const __restrict__ pInst) { + char *prog, *host, *text = NULL, *strtData = NULL, *tmp; + int hour, min, sec; + rsRetVal ret; + + hour = (rawMsg[0] ^ 0x30) * 10 + (rawMsg[1] ^ 0x30); + min = (rawMsg[2] ^ 0x30) * 10 + (rawMsg[3] ^ 0x30); + sec = (rawMsg[4] ^ 0x30) * 10 + (rawMsg[5] ^ 0x30); + + if (hour < 0 || hour > 23 || min < 0 || min > 59 + || sec < 0 || sec > 59) + return RS_RET_COULD_NOT_PARSE; + + host = rawMsg + ((rawMsg[10] == '.') ? 11 : 10); + + prog = memchr(host, '!', msgLen-(host - rawMsg)); + + if (prog == NULL) + return RS_RET_COULD_NOT_PARSE; + + prog++; + + strtData = memchr(prog, ':', msgLen-(prog - rawMsg)); + + if (strtData == NULL) + return RS_RET_COULD_NOT_PARSE; + + pMsg->tTIMESTAMP.year = pInst->currTm.tm_year + 1900; + pMsg->tTIMESTAMP.month = pInst->currTm.tm_mon + 1; + pMsg->tTIMESTAMP.day = pInst->currTm.tm_mday; + pMsg->tTIMESTAMP.hour = hour; + pMsg->tTIMESTAMP.minute = min; + pMsg->tTIMESTAMP.second = sec; + pMsg->tTIMESTAMP.OffsetMode = syslogTz.OffsetMode; + pMsg->tTIMESTAMP.OffsetHour = syslogTz.OffsetHour; + pMsg->tTIMESTAMP.OffsetMinute = syslogTz.OffsetMinute; + + pMsg->tTIMESTAMP.secfrac = atoi(rawMsg+7); + /* secfracprecision depends on the char on position 9 (case 1 or case 2) */ + pMsg->tTIMESTAMP.secfracPrecision = (rawMsg[9]=='.') ? 2 : 3; + + for (tmp = strtData ; prog < tmp && *tmp!='.'; tmp--) + ; + if (tmp > prog) + *tmp = '\0'; + else + *strtData = '\0'; + + strtData = strtData + 2; + + /* Case 4 */ + if (memcmp(strtData, "gtrid", 5) == 0) + { + strtData = memchr(strtData, ':', msgLen-(strtData - rawMsg)); + if (strtData != NULL) strtData += 2; + } + + text = strtData; + + /* ecid point to message text or the word ECID */ + if (strtData != NULL && memcmp(strtData, "ECID", 4) == 0) + { + text = memchr(strtData+6, '>', msgLen-(strtData-rawMsg)); + /* case 3 : we have the word ECID */ + if (text != NULL) + { + *(--strtData) = '['; + strtData[5] = '='; + strtData[6] = '\"'; + *text++ = '\"'; + *text++ = ']'; + text++; + ret = MsgAddToStructuredData(pMsg, (uchar*)strtData, text - strtData); + if (ret!=RS_RET_OK) + LogMsg(0, ret, LOG_WARNING, "Add StructuredData to message failed."); + } + } + + /* now compute the new length */ + msgLen -= text - rawMsg; + + if (text != NULL) + MsgSetRawMsg(pMsg, text, msgLen); + + MsgSetMSGoffs(pMsg, 0); + + /* set hostname */ + MsgSetHOSTNAME(pMsg, (const uchar*)host, prog - host - 1); + + if (*prog == '\0') + return 0; + + /* set procid */ + ret = MsgSetPROCID(pMsg, prog); + if (ret != RS_RET_OK) + LogMsg(0, ret, LOG_WARNING, "Set PROCID to message failed."); + + return RS_RET_OK; +} + +/* enqueue the read file line as a message. The provided string is + * not freed - this must be done by the caller. + */ +#define MAX_OFFSET_REPRESENTATION_NUM_BYTES 20 +static rsRetVal enqLine(instanceConf_t *const __restrict__ pInst, + cstr_t *const __restrict__ cstrLine) +{ + DEFiRet; + smsg_t *pMsg; + const size_t msgLen = cstrLen(cstrLine); + rsRetVal ret; + + if(msgLen == 0) { + /* we do not process empty lines */ + FINALIZE; + } + + CHKiRet(msgConstruct(&pMsg)); + + if (parseMsg(pMsg, (char*)rsCStrGetSzStrNoNULL(cstrLine), msgLen, pInst) != RS_RET_OK) { + if ((ret = msgDestruct(&pMsg)) != RS_RET_OK) + LogMsg(0, ret, LOG_ERR, "msgDestruct failed."); + FINALIZE; + } + + MsgSetInputName(pMsg, pInputName); + MsgSetTAG(pMsg, pInst->pszTag, pInst->lenTag); + msgSetPRI(pMsg, pInst->iFacility | pInst->iSeverity); + MsgSetRuleset(pMsg, pInst->pBindRuleset); + if ((ret = MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY)) != RS_RET_OK) + LogMsg(0, ret, LOG_WARNING, "Set Flow Control to message failed."); + if ((ret = MsgSetAPPNAME(pMsg, (const char*)pInst->pszTag)) != RS_RET_OK) + LogMsg(0, ret, LOG_WARNING, "Set APPNAME to message failed."); + + if ((iRet = ratelimitAddMsg(pInst->ratelimiter, &pInst->multiSub, pMsg)) != RS_RET_OK) { + if ((ret = msgDestruct(&pMsg)) != RS_RET_OK) + LogMsg(0, ret, LOG_ERR, "msgDestruct failed."); + } +finalize_it: + RETiRet; +} + +/* try to open a file which has a state file. If the state file does not + * exist or cannot be read, an error is returned. + */ +static rsRetVal ATTR_NONNULL(1) openFileWithStateFile(instanceConf_t *const __restrict__ pInst) +{ + DEFiRet; + strm_t *psSF = NULL; + uchar pszSFNam[MAXFNAME]; + size_t lenSFNam; + struct stat stat_buf; + uchar statefile[MAXFNAME]; + + uchar *const statefn = getStateFileName(pInst, statefile, sizeof(statefile), NULL); + DBGPRINTF("trying to open state for '%s', state file '%s'\n", + pInst->pszUlogBaseName, statefn); + + /* Get full path and file name */ + lenSFNam = getFullStateFileName(statefn, pszSFNam, sizeof(pszSFNam)); + + /* check if the file exists */ + if(stat((char*) pszSFNam, &stat_buf) == -1) { + if(errno == ENOENT) { + DBGPRINTF("NO state file (%s) exists for '%s'\n", pszSFNam, pInst->pszUlogBaseName); + ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); + } else { + char errStr[1024]; + rs_strerror_r(errno, errStr, sizeof(errStr)); + DBGPRINTF("error trying to access state file for '%s':%s\n", + pInst->pszUlogBaseName, errStr); + ABORT_FINALIZE(RS_RET_IO_ERROR); + } + } + + /* If we reach this point, we have a state file */ + + CHKiRet(strm.Construct(&psSF)); + CHKiRet(strm.SettOperationsMode(psSF, STREAMMODE_READ)); + CHKiRet(strm.SetsType(psSF, STREAMTYPE_FILE_SINGLE)); + CHKiRet(strm.SetFName(psSF, pszSFNam, lenSFNam)); + CHKiRet(strm.SetFileNotFoundError(psSF, 1)); + CHKiRet(strm.ConstructFinalize(psSF)); + + /* read back in the object */ + CHKiRet(obj.Deserialize(&pInst->pStrm, (uchar*) "strm", psSF, NULL, pInst)); + DBGPRINTF("deserialized state file, state file base name '%s', " + "configured base name '%s'\n", pInst->pStrm->pszFName, + pInst->pszUlogBaseName); + if(ustrcmp(pInst->pStrm->pszFName, pInst->pszCurrFName)) { + LogError(0, RS_RET_STATEFILE_WRONG_FNAME, "imtuxedoulog: state file '%s' " + "contains file name '%s', but is used for file '%s'. State " + "file deleted, starting from begin of file.", + pszSFNam, pInst->pStrm->pszFName, pInst->pszCurrFName); + + unlink((char*)pszSFNam); + ABORT_FINALIZE(RS_RET_STATEFILE_WRONG_FNAME); + } + + strm.CheckFileChange(pInst->pStrm); + CHKiRet(strm.SeekCurrOffs(pInst->pStrm)); + + /* note: we do not delete the state file, so that the last position remains + * known even in the case that rsyslogd aborts for some reason (like powerfail) + */ + +finalize_it: + if(psSF != NULL) + strm.Destruct(&psSF); + + RETiRet; +} + +/* try to open a file for which no state file exists. This function does NOT + * check if a state file actually exists or not -- this must have been + * checked before calling it. + */ +static rsRetVal openFileWithoutStateFile(instanceConf_t *const __restrict__ pInst) +{ + DEFiRet; + + DBGPRINTF("clean startup withOUT state file for '%s'\n", pInst->pszUlogBaseName); + if(pInst->pStrm != NULL) + strm.Destruct(&pInst->pStrm); + CHKiRet(strm.Construct(&pInst->pStrm)); + CHKiRet(strm.SettOperationsMode(pInst->pStrm, STREAMMODE_READ)); + CHKiRet(strm.SetsType(pInst->pStrm, STREAMTYPE_FILE_MONITOR)); + CHKiRet(strm.SetFName(pInst->pStrm, pInst->pszCurrFName, strlen((char*) pInst->pszCurrFName))); + CHKiRet(strm.SetFileNotFoundError(pInst->pStrm, 1)); + CHKiRet(strm.ConstructFinalize(pInst->pStrm)); + +finalize_it: + RETiRet; +} + +/* try to open a file. This involves checking if there is a status file and, + * if so, reading it in. Processing continues from the last known location. + */ +static rsRetVal openFile(instanceConf_t *const __restrict__ pInst) +{ + DEFiRet; + + CHKiRet_Hdlr(openFileWithStateFile(pInst)) { + CHKiRet(openFileWithoutStateFile(pInst)); + } + + CHKiRet(strm.SetbReopenOnTruncate(pInst->pStrm, 1)); + +finalize_it: + RETiRet; +} + +/* This function persists information for a specific file being monitored. + * To do so, it simply persists the stream object. We do NOT abort on error + * iRet as that makes matters worse (at least we can try persisting the others...). + * rgerhards, 2008-02-13 + */ +static void persistStrmState(instanceConf_t *pInst) +{ + DEFiRet; + strm_t *psSF = NULL; /* state file (stream) */ + size_t lenDir; + uchar statefile[MAXFNAME]; + + uchar *const statefn = getStateFileName(pInst, statefile, sizeof(statefile), NULL); + DBGPRINTF("persisting state for '%s' to file '%s'\n", + pInst->pszUlogBaseName, statefn); + CHKiRet(strm.Construct(&psSF)); + lenDir = ustrlen(glbl.GetWorkDir(runModConf->pConf)); + if(lenDir > 0) + CHKiRet(strm.SetDir(psSF, glbl.GetWorkDir(runModConf->pConf), lenDir)); + CHKiRet(strm.SettOperationsMode(psSF, STREAMMODE_WRITE_TRUNC)); + CHKiRet(strm.SetsType(psSF, STREAMTYPE_FILE_SINGLE)); + CHKiRet(strm.SetFName(psSF, statefn, strlen((char*) statefn))); + CHKiRet(strm.SetFileNotFoundError(psSF, 1)); + CHKiRet(strm.ConstructFinalize(psSF)); + + CHKiRet(strm.Serialize(pInst->pStrm, psSF)); + CHKiRet(strm.Flush(psSF)); + + CHKiRet(strm.Destruct(&psSF)); + +finalize_it: + if(psSF != NULL) + strm.Destruct(&psSF); + + if(iRet != RS_RET_OK) { + LogError(0, iRet, "imtuxedoulog: could not persist state " + "file %s - data may be repeated on next " + "startup. Is WorkDirectory set?", + statefn); + } +} + +/* The following is a cancel cleanup handler for strmReadLine(). It is necessary in case + * strmReadLine() is cancelled while processing the stream. -- rgerhards, 2008-03-27 + */ +static void pollFileCancelCleanup(void *pArg) +{ + cstr_t **ppCStr = (cstr_t**) pArg; + if(*ppCStr != NULL) { + rsCStrDestruct(ppCStr); + } +} + +static void pollFileReal(instanceConf_t *pInst, int *pbHadFileData, cstr_t **ppCStr) +{ + DEFiRet; + + int nProcessed = 0; + if(pInst->pStrm == NULL) { + CHKiRet(openFile(pInst)); /* open file */ + } + + /* loop below will be exited when strmReadLine() returns EOF */ + while(glbl.GetGlobalInputTermState() == 0) { + if(pInst->maxLinesAtOnce != 0 && nProcessed >= pInst->maxLinesAtOnce) + break; + CHKiRet(strm.ReadLine(pInst->pStrm, ppCStr, 0, 0, NULL, -1, NULL)); + ++nProcessed; + if(pbHadFileData != NULL) + *pbHadFileData = 1; /* this is just a flag, so set it and forget it */ + CHKiRet(enqLine(pInst, *ppCStr)); /* process line */ + rsCStrDestruct(ppCStr); /* discard string (must be done by us!) */ + + if(pInst->iPersistStateInterval > 0 && ++pInst->nRecords >= pInst->iPersistStateInterval) { + persistStrmState(pInst); + pInst->nRecords = 0; + } + } + +finalize_it: + multiSubmitFlush(&pInst->multiSub); + + if(*ppCStr != NULL) { + rsCStrDestruct(ppCStr); + } +} + +/* poll a file, need to check file rollover etc. open file if not open */ +static void pollFile(instanceConf_t *pInst, int *pbHadFileData) +{ + cstr_t *pCStr = NULL; + /* Note: we must do pthread_cleanup_push() immediately, because the POSIX macros + * otherwise do not work if I include the _cleanup_pop() inside an if... -- rgerhards, 2008-08-14 + */ + pthread_cleanup_push(pollFileCancelCleanup, &pCStr); + pollFileReal(pInst, pbHadFileData, &pCStr); + pthread_cleanup_pop(0); +} + + +/* create input instance, set default parameters, and + * add it to the list of instances. + */ +static rsRetVal ATTR_NONNULL(1) createInstance(instanceConf_t **const pinst) +{ + instanceConf_t *inst; + DEFiRet; + CHKmalloc(inst = malloc(sizeof(instanceConf_t))); + inst->next = NULL; + inst->pBindRuleset = NULL; + inst->ratelimiter = NULL; + inst->pStrm = NULL; + inst->multiSub.ppMsgs = NULL; + + inst->pszBindRuleset = NULL; + inst->pszUlogBaseName = NULL; + inst->pszCurrFName = NULL; + inst->pszTag = NULL; + inst->pszStateFile = NULL; + inst->nMultiSub = NUM_MULTISUB; + inst->iSeverity = 5; + inst->iFacility = 128; + inst->maxLinesAtOnce = 0; + inst->iPersistStateInterval = 0; + inst->nRecords = 0; + + *pinst = inst; +finalize_it: + RETiRet; +} + +/* This adds a new listener object to the bottom of the list, but + * it does NOT initialize any data members except for the list + * pointers themselves. + */ +static rsRetVal ATTR_NONNULL() lstnAdd(instanceConf_t *pInst) +{ + DEFiRet; + CHKiRet(ratelimitNew(&pInst->ratelimiter, "imtuxedoulog", (char*)pInst->pszUlogBaseName)); + CHKmalloc(pInst->multiSub.ppMsgs = malloc(pInst->nMultiSub * sizeof(smsg_t *))); + pInst->multiSub.maxElem = pInst->nMultiSub; + pInst->multiSub.nElem = 0; + + /* insert it at the begin of the list */ + pInst->prev = NULL; + pInst->next = confRoot; + + if (confRoot != NULL) + confRoot->prev = pInst; + + confRoot = pInst; + +finalize_it: + RETiRet; +} + +/* delete a listener object */ +static void ATTR_NONNULL(1) lstnDel(instanceConf_t *pInst) +{ + DBGPRINTF("lstnDel called for %s\n", pInst->pszUlogBaseName); + if(pInst->pStrm != NULL) { /* stream open? */ + persistStrmState(pInst); + strm.Destruct(&(pInst->pStrm)); + } + if (pInst->ratelimiter != NULL) + ratelimitDestruct(pInst->ratelimiter); + if (pInst->multiSub.ppMsgs != NULL) + free(pInst->multiSub.ppMsgs); + + free(pInst->pszUlogBaseName); + if (pInst->pszCurrFName != NULL) + free(pInst->pszCurrFName); + if (pInst->pszTag) + free(pInst->pszTag); + if (pInst->pszStateFile) + free(pInst->pszStateFile); + if (pInst->pszBindRuleset != NULL) + free(pInst->pszBindRuleset); + free(pInst); +} + +/* Monitor files in traditional polling mode. + */ +static void do_polling(void) +{ + int bHadFileData; /* were there at least one file with data during this run? */ + struct stat sb; + while(glbl.GetGlobalInputTermState() == 0) { + do { + instanceConf_t *pInst; + bHadFileData = 0; + for(pInst = confRoot ; pInst != NULL ; pInst = pInst->next) { + uchar *temp = mkFileNameWithTime(pInst); + + DBGPRINTF("imtuxedoulog: do_polling start '%s' / '%s'\n", pInst->pszUlogBaseName, temp); + /* + * Is the file name is different : a rotation time is reached + * If so, then it the new file exists ? and is a file ? + */ + if (temp && stat((const char*)temp, &sb) == 0 && S_ISREG(sb.st_mode) && + (pInst->pszCurrFName == NULL || + strcmp((char*)temp,(char*)pInst->pszCurrFName) != 0)) + { + DBGPRINTF("imtuxedoulog: timed file : rotation reach " + "switching form '%s' to '%s' !", + (char*)pInst->pszUlogBaseName, temp ); + + /* first of all change the listener datas */ + if (pInst->pszCurrFName != NULL) { + free(pInst->pszCurrFName); + strm.Destruct(&pInst->pStrm); + } + pInst->pszCurrFName = temp; + temp = NULL; + + /* And finish by destroy the stream object, so the next polling will recreate + * it based on new data. + */ + if(glbl.GetGlobalInputTermState() == 1) + break; /* terminate input! */ + } + if (temp) free(temp); + + /* let's poll the file */ + if (pInst->pszCurrFName != NULL) + pollFile(pInst, &bHadFileData); + + DBGPRINTF("imtuxedoulog: do_polling end for '%s'\n", pInst->pszUlogBaseName); + if (pInst->iPersistStateInterval == -1) + persistStrmState(pInst); + } + } while(bHadFileData == 1 && glbl.GetGlobalInputTermState() == 0); + + /* Note: the additional 10ns wait is vitally important. It guards rsyslog + * against totally hogging the CPU if the users selects a polling interval + * of 0 seconds. It doesn't hurt any other valid scenario. So do not remove. + * rgerhards, 2008-02-14 + */ + if(glbl.GetGlobalInputTermState() == 0) + srSleep(iPollInterval, 10); + } +} + +BEGINnewInpInst + struct cnfparamvals *pvals; + instanceConf_t *inst; + int i; +CODESTARTnewInpInst + DBGPRINTF("newInpInst (imtuxedoulog)\n"); + + pvals = nvlstGetParams(lst, &inppblk, NULL); + if(pvals == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + DBGPRINTF("input param blk in imtuxedoulog:\n"); + cnfparamsPrint(&inppblk, pvals); + } + + CHKiRet(createInstance(&inst)); + + for(i = 0 ; i < inppblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(inppblk.descr[i].name, "ulogbase")) { + inst->pszUlogBaseName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "tag")) { + inst->pszTag = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + inst->lenTag = es_strlen(pvals[i].val.d.estr); + } else if(!strcmp(inppblk.descr[i].name, "ruleset")) { + inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(inppblk.descr[i].name, "severity")) { + inst->iSeverity = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "facility")) { + inst->iFacility = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "maxlinesatonce")) { + inst->maxLinesAtOnce = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "persiststateinterval")) { + inst->iPersistStateInterval = pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "maxsubmitatonce")) { + inst->nMultiSub = pvals[i].val.d.n; + } else { + DBGPRINTF("program error, non-handled " + "param '%s'\n", inppblk.descr[i].name); + } + } + if(inst->pszUlogBaseName == NULL) { + lstnDel(inst); + LogError(0, RS_RET_FILE_NOT_SPECIFIED, + "ulogbase is not configured - no input will be gathered"); + ABORT_FINALIZE(RS_RET_FILE_NOT_SPECIFIED); + } + + if ((iRet = lstnAdd(inst)) != RS_RET_OK) { + LogError(0, iRet, + "add input %s to list failed", inst->pszUlogBaseName); + lstnDel(inst); + ABORT_FINALIZE(iRet); + } + +finalize_it: +CODE_STD_FINALIZERnewInpInst + cnfparamvalsDestruct(pvals, &inppblk); +ENDnewInpInst + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +instanceConf_t *inst; +CODESTARTcheckCnf + for(inst = confRoot ; inst != NULL ; inst = inst->next) { + std_checkRuleset(pModConf , inst); + } +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + +BEGINrunInput +CODESTARTrunInput + do_polling(); + DBGPRINTF("terminating upon request of rsyslog core\n"); +ENDrunInput + +BEGINwillRun +CODESTARTwillRun + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imtuxedoulog"), sizeof("imtuxedoulog") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); +finalize_it: +ENDwillRun + +BEGINafterRun +CODESTARTafterRun + while(confRoot != NULL) { + instanceConf_t *inst = confRoot; + confRoot = confRoot->next; + lstnDel(inst); + } + + if(pInputName != NULL) + prop.Destruct(&pInputName); +ENDafterRun + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURENonCancelInputTermination) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +BEGINmodExit +CODESTARTmodExit + /* release objects we used */ + objRelease(strm, CORE_COMPONENT); + objRelease(glbl, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + +static inline void +std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) +{ + LogError(0, NO_ERRCODE, "imtuxedoulog: ruleset '%s' for ULOG base %s not found - " + "using default ruleset instead", inst->pszBindRuleset, + inst->pszUlogBaseName); +} + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(strm, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); + CHKiRet(objUse(prop, CORE_COMPONENT)); +ENDmodInit diff --git a/contrib/mmcount/Makefile.am b/contrib/mmcount/Makefile.am new file mode 100644 index 0000000..9c8c99d --- /dev/null +++ b/contrib/mmcount/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmcount.la + +mmcount_la_SOURCES = mmcount.c +mmcount_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmcount_la_LDFLAGS = -module -avoid-version +mmcount_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/mmcount/Makefile.in b/contrib/mmcount/Makefile.in new file mode 100644 index 0000000..b14f90b --- /dev/null +++ b/contrib/mmcount/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/mmcount +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +mmcount_la_DEPENDENCIES = +am_mmcount_la_OBJECTS = mmcount_la-mmcount.lo +mmcount_la_OBJECTS = $(am_mmcount_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mmcount_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(mmcount_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/mmcount_la-mmcount.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(mmcount_la_SOURCES) +DIST_SOURCES = $(mmcount_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = mmcount.la +mmcount_la_SOURCES = mmcount.c +mmcount_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmcount_la_LDFLAGS = -module -avoid-version +mmcount_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmcount/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/mmcount/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mmcount.la: $(mmcount_la_OBJECTS) $(mmcount_la_DEPENDENCIES) $(EXTRA_mmcount_la_DEPENDENCIES) + $(AM_V_CCLD)$(mmcount_la_LINK) -rpath $(pkglibdir) $(mmcount_la_OBJECTS) $(mmcount_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmcount_la-mmcount.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mmcount_la-mmcount.lo: mmcount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmcount_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmcount_la-mmcount.lo -MD -MP -MF $(DEPDIR)/mmcount_la-mmcount.Tpo -c -o mmcount_la-mmcount.lo `test -f 'mmcount.c' || echo '$(srcdir)/'`mmcount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmcount_la-mmcount.Tpo $(DEPDIR)/mmcount_la-mmcount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmcount.c' object='mmcount_la-mmcount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmcount_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmcount_la-mmcount.lo `test -f 'mmcount.c' || echo '$(srcdir)/'`mmcount.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/mmcount_la-mmcount.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/mmcount_la-mmcount.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/mmcount/mmcount.c b/contrib/mmcount/mmcount.c new file mode 100644 index 0000000..9c5ad55 --- /dev/null +++ b/contrib/mmcount/mmcount.c @@ -0,0 +1,351 @@ +/* mmcount.c + * count messages by priority or json property of given app-name. + * + * Copyright 2013 Red Hat Inc. + * Copyright 2014 Rainer Gerhards + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <stdint.h> +#include <json.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "hashtable.h" + + +#define JSON_COUNT_NAME "!mmcount" +#define SEVERITY_COUNT 8 + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("mmcount") + + +DEF_OMOD_STATIC_DATA + +/* config variables */ + +typedef struct _instanceData { + char *pszAppName; + int severity[SEVERITY_COUNT]; + char *pszKey; + char *pszValue; + int valueCounter; + struct hashtable *ht; + pthread_mutex_t mut; +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; +} wrkrInstanceData_t; + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ +}; +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current exec process */ + + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "appname", eCmdHdlrGetWord, 0 }, + { "key", eCmdHdlrGetWord, 0 }, + { "value", eCmdHdlrGetWord, 0 }, +}; +static struct cnfparamblk actpblk = + { CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr + }; + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + +BEGINcreateInstance +CODESTARTcreateInstance + pthread_mutex_init(&pData->mut, NULL); +ENDcreateInstance + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + + +BEGINfreeInstance +CODESTARTfreeInstance +ENDfreeInstance + + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + +static inline void +setInstParamDefaults(instanceData *pData) +{ + int i; + + pData->pszAppName = NULL; + for (i = 0; i < SEVERITY_COUNT; i++) + pData->severity[i] = 0; + pData->pszKey = NULL; + pData->pszValue = NULL; + pData->valueCounter = 0; + pData->ht = NULL; +} + +static unsigned int +hash_from_key_fn(void *k) +{ + return *(unsigned int *)k; +} + +static int +key_equals_fn(void *k1, void *k2) +{ + return (*(unsigned int *)k1 == *(unsigned int *)k2); +} + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; +CODESTARTnewActInst + DBGPRINTF("newActInst (mmcount)\n"); + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CODE_STD_STRING_REQUESTnewActInst(1) + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(actpblk.descr[i].name, "appname")) { + pData->pszAppName = es_str2cstr(pvals[i].val.d.estr, NULL); + continue; + } + if(!strcmp(actpblk.descr[i].name, "key")) { + pData->pszKey = es_str2cstr(pvals[i].val.d.estr, NULL); + continue; + } + if(!strcmp(actpblk.descr[i].name, "value")) { + pData->pszValue = es_str2cstr(pvals[i].val.d.estr, NULL); + continue; + } + dbgprintf("mmcount: program error, non-handled " + "param '%s'\n", actpblk.descr[i].name); + } + + if(pData->pszAppName == NULL) { + dbgprintf("mmcount: action requires a appname"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(pData->pszKey != NULL && pData->pszValue == NULL) { + if(NULL == (pData->ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL))) { + DBGPRINTF("mmcount: error creating hash table!\n"); + ABORT_FINALIZE(RS_RET_ERR); + } + } +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +static int * +getCounter(struct hashtable *ht, const char *str) { + unsigned int key; + int *pCounter; + unsigned int *pKey; + + /* we dont store str as key, instead we store hash of the str + as key to reduce memory usage */ + key = hash_from_string((char*)str); + pCounter = hashtable_search(ht, &key); + if(pCounter) { + return pCounter; + } + + /* counter is not found for the str, so add new entry and + return the counter */ + if(NULL == (pKey = (unsigned int*)malloc(sizeof(unsigned int)))) { + DBGPRINTF("mmcount: memory allocation for key failed\n"); + return NULL; + } + *pKey = key; + + if(NULL == (pCounter = (int*)malloc(sizeof(int)))) { + DBGPRINTF("mmcount: memory allocation for value failed\n"); + free(pKey); + return NULL; + } + *pCounter = 0; + + if(!hashtable_insert(ht, pKey, pCounter)) { + DBGPRINTF("mmcount: inserting element into hashtable failed\n"); + free(pKey); + free(pCounter); + return NULL; + } + return pCounter; +} + +BEGINdoAction_NoStrings + smsg_t **ppMsg = (smsg_t **) pMsgData; + smsg_t *pMsg = ppMsg[0]; + char *appname; + struct json_object *json = NULL; + struct json_object *keyjson = NULL; + const char *pszValue; + int *pCounter; + instanceData *const pData = pWrkrData->pData; +CODESTARTdoAction + appname = getAPPNAME(pMsg, LOCK_MUTEX); + + pthread_mutex_lock(&pData->mut); + if(0 != strcmp(appname, pData->pszAppName)) { + /* we are not working for this appname. nothing to do */ + ABORT_FINALIZE(RS_RET_OK); + } + + if(!pData->pszKey) { + /* no key given for count, so we count severity */ + if(pMsg->iSeverity < SEVERITY_COUNT) { + pData->severity[pMsg->iSeverity]++; + json = json_object_new_int(pData->severity[pMsg->iSeverity]); + } + ABORT_FINALIZE(RS_RET_OK); + } + + /* key is given, so get the property json */ + msgPropDescr_t pProp; + msgPropDescrFill(&pProp, (uchar*)pData->pszKey, strlen(pData->pszKey)); + rsRetVal localRet = msgGetJSONPropJSON(pMsg, &pProp, &keyjson); + msgPropDescrDestruct(&pProp); + if(localRet != RS_RET_OK) { + /* key not found in the message. nothing to do */ + ABORT_FINALIZE(RS_RET_OK); + } + + /* key found, so get the value */ + pszValue = (char*)json_object_get_string(keyjson); + if(pszValue == NULL) { /* json null object returns NULL! */ + pszValue = ""; + } + + if(pData->pszValue) { + /* value also given for count */ + if(!strcmp(pszValue, pData->pszValue)) { + /* count for (value and key and appname) matched */ + pData->valueCounter++; + json = json_object_new_int(pData->valueCounter); + } + ABORT_FINALIZE(RS_RET_OK); + } + + /* value is not given, so we count for each value of given key */ + pCounter = getCounter(pData->ht, pszValue); + if(pCounter) { + (*pCounter)++; + json = json_object_new_int(*pCounter); + } +finalize_it: + pthread_mutex_unlock(&pData->mut); + + if(json) { + msgAddJSON(pMsg, (uchar *)JSON_COUNT_NAME, json, 0, 0); + } +ENDdoAction + + +NO_LEGACY_CONF_parseSelectorAct + + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +ENDqueryEtryPt + + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmcount: module compiled with rsyslog version %s.\n", VERSION); +ENDmodInit diff --git a/contrib/mmdarwin/Makefile.am b/contrib/mmdarwin/Makefile.am new file mode 100644 index 0000000..4b88691 --- /dev/null +++ b/contrib/mmdarwin/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmdarwin.la + +mmdarwin_la_SOURCES = mmdarwin.c protocol.h +mmdarwin_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmdarwin_la_LDFLAGS = -module -avoid-version +mmdarwin_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/mmdarwin/Makefile.in b/contrib/mmdarwin/Makefile.in new file mode 100644 index 0000000..60812d4 --- /dev/null +++ b/contrib/mmdarwin/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/mmdarwin +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +mmdarwin_la_DEPENDENCIES = +am_mmdarwin_la_OBJECTS = mmdarwin_la-mmdarwin.lo +mmdarwin_la_OBJECTS = $(am_mmdarwin_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mmdarwin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(mmdarwin_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(mmdarwin_la_SOURCES) +DIST_SOURCES = $(mmdarwin_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = mmdarwin.la +mmdarwin_la_SOURCES = mmdarwin.c protocol.h +mmdarwin_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmdarwin_la_LDFLAGS = -module -avoid-version +mmdarwin_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmdarwin/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/mmdarwin/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mmdarwin.la: $(mmdarwin_la_OBJECTS) $(mmdarwin_la_DEPENDENCIES) $(EXTRA_mmdarwin_la_DEPENDENCIES) + $(AM_V_CCLD)$(mmdarwin_la_LINK) -rpath $(pkglibdir) $(mmdarwin_la_OBJECTS) $(mmdarwin_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mmdarwin_la-mmdarwin.lo: mmdarwin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmdarwin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmdarwin_la-mmdarwin.lo -MD -MP -MF $(DEPDIR)/mmdarwin_la-mmdarwin.Tpo -c -o mmdarwin_la-mmdarwin.lo `test -f 'mmdarwin.c' || echo '$(srcdir)/'`mmdarwin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmdarwin_la-mmdarwin.Tpo $(DEPDIR)/mmdarwin_la-mmdarwin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmdarwin.c' object='mmdarwin_la-mmdarwin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmdarwin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmdarwin_la-mmdarwin.lo `test -f 'mmdarwin.c' || echo '$(srcdir)/'`mmdarwin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/mmdarwin/mmdarwin.c b/contrib/mmdarwin/mmdarwin.c new file mode 100644 index 0000000..e36dbde --- /dev/null +++ b/contrib/mmdarwin/mmdarwin.c @@ -0,0 +1,953 @@ +/* Copyright 2019 Advens + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <stdint.h> +#include <pthread.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "parserif.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/un.h> +#include <sys/socket.h> +#include <uuid/uuid.h> +#include <json.h> + +#include "protocol.h" /* custom file written for Darwin */ + +#define JSON_DEFAULT_CONTAINER "!mmdarwin" +#define JSON_DARWIN_ID "darwin_id" +#define INVLD_SOCK -1 +#define INITIAL_BUFFER_SIZE 32 +#define BUFFER_DEFAULT_MAX_SIZE 65536 + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("mmdarwin") + +DEFobjCurrIf(glbl) +DEF_OMOD_STATIC_DATA + +typedef struct dyn_buffer_t +{ + char *buffer; + size_t bufferAllocSize; + size_t bufferMsgSize; + size_t bufferMaxSize; +} dyn_buffer; + +/* config variables */ +typedef struct _instanceData +{ + char *pUUIDKey; /* the key to the UUID generated by an mmdarwin instance */ + char *pCertitudeKey; /* the key name to save in the enriched log + line the certitude obtained from Darwin */ + uchar *pSockName; /* the socket path of the filter which will be used by + Darwin */ + unsigned long long int filterCode; /* the filter code associated to the filter which will be used + by Darwin */ + enum darwin_filter_response_type response; /* the type of response for Darwin: no / back / darwin / both */ + struct + { + int nmemb; + char **name; + char **varname; + } fieldList; /* our keys (fields) to be extracted from the JSON-parsed log line */ + unsigned int socketMaxUse; + sbool sendPartial; +} instanceData; + +typedef struct wrkrInstanceData +{ + instanceData *pData; + int sock; /* the socket of the filter which will be used by Darwin */ + struct sockaddr_un addr; /* the sockaddr_un used to connect to the Darwin filter */ + uint8_t pktSentSocket; + dyn_buffer darwinBody; /* the body object used (and reused) to hold data to send to Darwin */ + dyn_buffer fieldBuffer; +} wrkrInstanceData_t; + +struct modConfData_s +{ + /* our overall config object */ + rsconf_t *pConf; + const char *container; +}; + +/* modConf ptr to use for the current load process */ +static modConfData_t *loadModConf = NULL; +/* modConf ptr to use for the current exec process */ +static modConfData_t *runModConf = NULL; + +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + {"container", eCmdHdlrGetWord, 0}, +}; +static struct cnfparamblk modpblk = + {CNFPARAMBLK_VERSION, + sizeof(modpdescr) / sizeof(struct cnfparamdescr), + modpdescr}; + +/* tables for interfacing with the v6 config system + * action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + {"key", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, + {"socketpath", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, + {"fields", eCmdHdlrArray, CNFPARAM_REQUIRED}, + {"filtercode", eCmdHdlrGetWord, 0}, /* optional parameter */ + {"response", eCmdHdlrGetWord, 0}, /* optional parameter */ + {"send_partial", eCmdHdlrBinary, 0}, /* optional parameter */ + {"socket_max_use", eCmdHdlrNonNegInt, 0}, /* optional parameter - will disappear in future updates */ +}; +static struct cnfparamblk actpblk = { + CNFPARAMBLK_VERSION, + sizeof(actpdescr) / sizeof(struct cnfparamdescr), + actpdescr}; + +/* custom functions */ +#define min(a, b) \ + ({ __typeof__ (a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) + +static rsRetVal openSocket(wrkrInstanceData_t *pWrkrData); +static rsRetVal closeSocket(wrkrInstanceData_t *pWrkrData); +static rsRetVal doTryResume(wrkrInstanceData_t *pWrkrData); + +static rsRetVal sendMsg(wrkrInstanceData_t *pWrkrData, void *msg, size_t len); +static rsRetVal receiveMsg(wrkrInstanceData_t *pWrkrData, void *response, size_t len); + +const char* get_uuid_object(smsg_t *const pMsg); +int get_field(smsg_t *const pMsg, const char *pFieldName, char **ppRetString); +int expand_buffer(dyn_buffer *pBody, size_t new_size); +int add_field_to_body(dyn_buffer *pBody, const char *field, size_t size); +int start_new_line(dyn_buffer *pBody); +int end_body(dyn_buffer *pBody); + +/* open socket to remote system + */ +static rsRetVal openSocket(wrkrInstanceData_t *pWrkrData) +{ + DEFiRet; + assert(pWrkrData->sock == INVLD_SOCK); + + if ((pWrkrData->sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + { + char errStr[1024]; + int eno = errno; + DBGPRINTF("mmdarwin::openSocket:: error %d creating AF_UNIX/SOCK_STREAM: %s.\n", + eno, rs_strerror_r(eno, errStr, sizeof(errStr))); + pWrkrData->sock = INVLD_SOCK; + ABORT_FINALIZE(RS_RET_NO_SOCKET); + } + + memset(&pWrkrData->addr, 0, sizeof(struct sockaddr_un)); + pWrkrData->addr.sun_family = AF_UNIX; + strncpy(pWrkrData->addr.sun_path, (char *)pWrkrData->pData->pSockName, sizeof(pWrkrData->addr.sun_path) - 1); + + DBGPRINTF("mmdarwin::openSocket:: connecting to Darwin...\n"); + + if (connect(pWrkrData->sock, (struct sockaddr *)&pWrkrData->addr, sizeof(struct sockaddr_un)) == -1) + { + LogError(errno, RS_RET_NO_SOCKET, "mmdarwin::openSocket:: error connecting to Darwin " + "via socket '%s'", + pWrkrData->pData->pSockName); + + pWrkrData->sock = INVLD_SOCK; + ABORT_FINALIZE(RS_RET_NO_SOCKET); + } + + DBGPRINTF("mmdarwin::openSocket:: connected !\n"); +finalize_it: + if (iRet != RS_RET_OK) + { + closeSocket(pWrkrData); + } + RETiRet; +} + +/* close socket to remote system + */ +static rsRetVal closeSocket(wrkrInstanceData_t *pWrkrData) +{ + DEFiRet; + if (pWrkrData->sock != INVLD_SOCK) + { + if (close(pWrkrData->sock) != 0) + { + char errStr[1024]; + int eno = errno; + DBGPRINTF("mmdarwin::closeSocket:: error %d closing the socket: %s.\n", + eno, rs_strerror_r(eno, errStr, sizeof(errStr))); + } + pWrkrData->sock = INVLD_SOCK; + } + RETiRet; +} + +/* try to resume connection if it is not ready + */ +static rsRetVal doTryResume(wrkrInstanceData_t *pWrkrData) +{ + DEFiRet; + + DBGPRINTF("mmdarwin::doTryResume:: trying to resume\n"); + closeSocket(pWrkrData); + iRet = openSocket(pWrkrData); + + if (iRet != RS_RET_OK) + { + iRet = RS_RET_SUSPENDED; + } + + RETiRet; +} + +/* send a message via TCP + * inspired by rgehards, 2007-12-20 + */ +static rsRetVal sendMsg(wrkrInstanceData_t *pWrkrData, void *msg, size_t len) +{ + DEFiRet; + + DBGPRINTF("mmdarwin::sendMsg:: sending message to Darwin...\n"); + + if (pWrkrData->sock == INVLD_SOCK) + { + CHKiRet(doTryResume(pWrkrData)); + } + + if (pWrkrData->sock != INVLD_SOCK) + { + if (send(pWrkrData->sock, msg, len, 0) == -1) + { + char errStr[1024]; + DBGPRINTF("mmdarwin::sendData:: error while sending data: error[%d] -> %s\n", + errno, rs_strerror_r(errno, errStr, sizeof(errStr))); + iRet = RS_RET_SUSPENDED; + } + } + +finalize_it: + RETiRet; +} + +/* receive a message via TCP + * inspired by rgehards, 2007-12-20 + */ +static rsRetVal receiveMsg(wrkrInstanceData_t *pWrkrData, void *response, size_t len) +{ + DEFiRet; + + DBGPRINTF("mmdarwin::receiveMsg:: receiving message from Darwin...\n"); + + if (pWrkrData->sock == INVLD_SOCK) + { + CHKiRet(doTryResume(pWrkrData)); + } + + if (pWrkrData->sock != INVLD_SOCK) + { + if (recv(pWrkrData->sock, response, len, MSG_WAITALL) <= 0) + { + char errStr[1024]; + DBGPRINTF("mmdarwin::receiveMsg:: error while receiving data: error[%d] -> %s\n", + errno, rs_strerror_r(errno, errStr, sizeof(errStr))); + iRet = RS_RET_NONE; + } + } + +finalize_it: + RETiRet; +} + +/** + * Get the string corresponding to a field supposedly present in the provided message + * + * params: + * - pMsg: a pointer to the rsyslog message where the field should be + * - pFieldName: a nul-terminated pointer to string representing the name of the field to search for + * - ppRetString: the pointer to contain the potential return string + * + * return: 1 if a string was put in ppRetString, 0 otherwise + * + * note: the string placed in ppRetString should be freed by the caller + */ +int get_field(smsg_t *const pMsg, const char *pFieldName, char **ppRetString) +{ + DBGPRINTF("mmdarwin::get_field:: getting key '%s' in msg\n", pFieldName); + struct json_object *pJson = NULL; + char *pFieldString = NULL; + int retVal = 0; + + msgPropDescr_t propDesc; + msgPropDescrFill(&propDesc, (uchar *)pFieldName, strlen(pFieldName)); + msgGetJSONPropJSONorString(pMsg, &propDesc, &pJson, (uchar **)&pFieldString); + + if (pFieldString) + { + *ppRetString = pFieldString; + DBGPRINTF("mmdarwin::get_field:: got string\n"); + retVal = 1; + } + else if (pJson) + { + pFieldString = (char *)json_object_get_string(pJson); + if (pFieldString) + { + *ppRetString = strdup(pFieldString); + retVal = 1; + DBGPRINTF("mmdarwin::get_field:: got string from json\n"); + json_object_put(pJson); + } + } + + msgPropDescrDestruct(&propDesc); + return retVal; +} + +/** + * expands the buffer object in the dyn_buffer object + * + * params: + * - pBody: a pointer to the concerned structure to expand + * - new_size: the new size to give to the underlying buffer + * + * return: 0 if the expansion was successful, -1 otherwise + */ +int expand_buffer(dyn_buffer *pBody, size_t new_size) +{ + /* return error if new_size tries to exceed max defined size */ + if (new_size > pBody->bufferMaxSize) + return -1; + while (pBody->bufferAllocSize < new_size) + pBody->bufferAllocSize += INITIAL_BUFFER_SIZE; + + DBGPRINTF("mmdarwin::expand_buffer:: expanding buffer to %zu\n", pBody->bufferAllocSize); + + char *tmp = realloc(pBody->buffer, pBody->bufferAllocSize * sizeof(char)); + + if (!tmp) + { + DBGPRINTF("mmdarwin::expand_buffer:: could not resize buffer\n"); + return -1; + } + + pBody->buffer = tmp; + return 0; +} + +/** + * adds a field to the dyn_buffer buffer + * + * params: + * - pBody: the pointer on the dyn_buffer structure + * - field: the potentially not null-terminated string to add as a field to the dyn_buffer + * - size: the size of the string (without the '\0' character) + * + * return: 0 if the field was indeed added to the dyn_buffer, -1 otherwise + */ +int add_field_to_body(dyn_buffer *pBody, const char *field, size_t size) +{ + /* get required additional size for field, quotes, colon, and \0 + and potentially also for the beginning of the message structure */ + int beginning = (pBody->bufferMsgSize == 0) ? 2 : 0; + size_t requiredBodySize = pBody->bufferMsgSize + size + 4 + beginning; + + /* resize body buffer if necessary */ + if (requiredBodySize > pBody->bufferAllocSize) + { + if (expand_buffer(pBody, requiredBodySize) != 0) + { + return -1; + } + } + + /* add message structure beginning if current message is empty */ + if (!pBody->bufferMsgSize) + { + pBody->buffer[0] = '['; + pBody->buffer[1] = '['; + pBody->bufferMsgSize += 2; + } + + /* add field with quotes and colon */ + pBody->buffer[pBody->bufferMsgSize++] = '\"'; + memcpy((void *)&pBody->buffer[pBody->bufferMsgSize], (const void *)field, size); + pBody->bufferMsgSize += size; + pBody->buffer[pBody->bufferMsgSize++] = '\"'; + pBody->buffer[pBody->bufferMsgSize++] = ','; + + return 0; +} + +/** + * small helper function to start a new input line (used for bulk-calls) in the dyn_buffer. + * will close current line with a ']' and start the next with a '['. + * will also remove leading ',' in fields list. + * + * params: + * - pBody: the pointer on the dyn_buffer on which to start a new input line + * + * return: 0 if successful, -1 otherwise + */ +int start_new_line(dyn_buffer *pBody) +{ + /* don't if the message is empty */ + if (!pBody->bufferMsgSize) + { + return -1; + } + + DBGPRINTF("mmdarwin::start_new_line:: starting new line entry in body\n"); + + if (pBody->bufferAllocSize < pBody->bufferMsgSize + 2) + { + if (expand_buffer(pBody, pBody->bufferAllocSize + 2) != 0) + { + return -1; + } + } + + pBody->buffer[pBody->bufferMsgSize - 1] = ']'; + pBody->buffer[pBody->bufferMsgSize++] = ','; + pBody->buffer[pBody->bufferMsgSize++] = '['; + return 0; +} + +/** + * small helper function to close the dyn_buffer structure. + * will close the line list with two ']' and will remove the leading ',' in the fields list + * + * params: + * - pBody: the pointer on the dyn_buffer on which to start a new input line + * + * return: 0 if successful, -1 otherwise + */ +int end_body(dyn_buffer *pBody) +{ + /* don't if the message is empty */ + if (!pBody->bufferMsgSize) + { + return -1; + } + + DBGPRINTF("mmdarwin::end_body:: finishing body structure\n"); + + if (pBody->bufferAllocSize < pBody->bufferMsgSize + 2) + { + if (expand_buffer(pBody, pBody->bufferAllocSize + 2) != 0) + { + return -1; + } + } + + pBody->buffer[pBody->bufferMsgSize - 1] = ']'; + pBody->buffer[pBody->bufferMsgSize++] = ']'; + pBody->buffer[pBody->bufferMsgSize++] = '\0'; + return 0; +} + +/** + * Get the potential existing uuid put by previous mmdarwin call in a json + * + * params: + * - pJson: the pointer on the json + * + * return: a valid json_object pointer if found, NULL otherwise + */ +const char* get_uuid_object(smsg_t *const pMsg) { + struct json_object *mmdarwin_object = NULL; + const char *result = NULL, *key = NULL; + + msgPropDescr_t propDesc; + msgPropDescrFill(&propDesc, (uchar *)runModConf->container, strlen(runModConf->container)); + msgGetJSONPropJSON(pMsg, &propDesc, &mmdarwin_object); + + if(mmdarwin_object) { + struct json_object_iterator it = json_object_iter_begin(mmdarwin_object); + struct json_object_iterator itEnd = json_object_iter_end(mmdarwin_object); + + while(!json_object_iter_equal(&it, &itEnd)) { + key = json_object_iter_peek_name(&it); + + if(!strcmp(key, JSON_DARWIN_ID)) { + // should always be a (non-empty) null-terminated string, safe to use with strdup() + result = strdup(json_object_get_string(json_object_iter_peek_value(&it))); + break; + } + + json_object_iter_next(&it); + } + json_object_put(mmdarwin_object); + } + + msgPropDescrDestruct(&propDesc); + return result; +} + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; +pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf + free((void *)pModConf->container); +ENDfreeCnf + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + DBGPRINTF("%s\n", pData->pSockName); +ENDdbgPrintInstInfo + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance + pWrkrData->pktSentSocket = 0; + pWrkrData->darwinBody.bufferAllocSize = 0; + pWrkrData->darwinBody.bufferMaxSize = BUFFER_DEFAULT_MAX_SIZE; + pWrkrData->darwinBody.bufferMsgSize = 0; + pWrkrData->sock = INVLD_SOCK; +ENDcreateWrkrInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + +BEGINfreeInstance +CODESTARTfreeInstance + if (pData->fieldList.name != NULL) + { + for (int i = 0; i < pData->fieldList.nmemb; ++i) + { + free(pData->fieldList.name[i]); + free(pData->fieldList.varname[i]); + } + free(pData->fieldList.name); + free(pData->fieldList.varname); + } + free(pData->pUUIDKey); + free(pData->pCertitudeKey); + free(pData->pSockName); +ENDfreeInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance + closeSocket(pWrkrData); + free(pWrkrData->darwinBody.buffer); +ENDfreeWrkrInstance + +BEGINsetModCnf +struct cnfparamvals *pvals = NULL; +int i; +CODESTARTsetModCnf + loadModConf->container = NULL; + pvals = nvlstGetParams(lst, &modpblk, NULL); + if (pvals == NULL) + { + LogError(0, RS_RET_MISSING_CNFPARAMS, + "mmdarwin: error processing module config parameters missing [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + if (Debug) + { + DBGPRINTF("mmdarwin::setModCnf:: module (global) param blk for mmdarwin:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for (i = 0; i < modpblk.nParams; ++i) + { + if (!pvals[i].bUsed) + continue; + if (!strcmp(modpblk.descr[i].name, "container")) + { + loadModConf->container = es_str2cstr(pvals[i].val.d.estr, NULL); + if(loadModConf->container[0] != '!' && loadModConf->container[0] != '.') { + LogError(0, RS_RET_INVALID_PARAMS, "mmdarwin: container should either" + " begin with '!' or '.'\n"); + ABORT_FINALIZE(RS_RET_INVALID_PARAMS); + } + } + else + { + DBGPRINTF("mmdarwin::setModCnf:: program error, non-handled " + "param '%s'\n", + modpblk.descr[i].name); + } + } + + if (loadModConf->container == NULL) + { + CHKmalloc(loadModConf->container = strdup(JSON_DEFAULT_CONTAINER)); + } + +finalize_it : + if (pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + +static inline void setInstParamDefaults(instanceData *pData) +{ + DBGPRINTF("mmdarwin::setInstParamDefaults::\n"); + pData->pUUIDKey = NULL; + pData->pCertitudeKey = NULL; + pData->pSockName = NULL; + pData->fieldList.nmemb = 0; + pData->filterCode = DARWIN_FILTER_CODE_NO; + pData->response = DARWIN_RESPONSE_SEND_NO; + pData->socketMaxUse = 0; + pData->sendPartial = 0; +} + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; +CODESTARTnewActInst + DBGPRINTF("mmdarwin::newActInst::\n"); + if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) + { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CODE_STD_STRING_REQUESTnewActInst(1) + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for (i = 0; i < actpblk.nParams; ++i) + { + if (!pvals[i].bUsed) + continue; + + if (!strcmp(actpblk.descr[i].name, "key")) + { + char *key = es_str2cstr(pvals[i].val.d.estr, NULL); + char vnamebuf[1024]; + snprintf(vnamebuf, sizeof(vnamebuf), "%s!%s", loadModConf->container, key); + CHKmalloc(pData->pCertitudeKey = strdup(vnamebuf)); + free(key); + DBGPRINTF("mmdarwin::newActInst:: certitudeKey is %s\n", pData->pCertitudeKey); + } + else if (!strcmp(actpblk.descr[i].name, "socketpath")) + { + pData->pSockName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); + DBGPRINTF("mmdarwin::newActInst:: sockName is %s\n", pData->pSockName); + } + else if (!strcmp(actpblk.descr[i].name, "socket_max_use")) + { + pData->socketMaxUse = (uint32_t)pvals[i].val.d.n; + DBGPRINTF("mmdarwin::newActInst:: socketMaxUse is %d\n", pData->socketMaxUse); + } + else if (!strcmp(actpblk.descr[i].name, "send_partial")) + { + pData->sendPartial = (sbool)pvals[i].val.d.n; + if (pData->sendPartial) + { + DBGPRINTF("mmdarwin::newActInst:: sending bodies even if fields are missing\n"); + } + else + { + DBGPRINTF("mmdarwin::newActInst:: only sending complete bodies\n"); + } + } + else if (!strcmp(actpblk.descr[i].name, "response")) + { + char *response = es_str2cstr(pvals[i].val.d.estr, NULL); + + if (!strcmp(response, "no")) + { + pData->response = DARWIN_RESPONSE_SEND_NO; + DBGPRINTF("mmdarwin::newActInst:: response type is 'no'\n"); + } + else if (!strcmp(response, "back")) + { + pData->response = DARWIN_RESPONSE_SEND_BACK; + DBGPRINTF("mmdarwin::newActInst:: response type is 'back'\n"); + } + else if (!strcmp(response, "darwin")) + { + pData->response = DARWIN_RESPONSE_SEND_DARWIN; + DBGPRINTF("mmdarwin::newActInst:: response type is 'darwin'\n"); + } + else if (!strcmp(response, "both")) + { + pData->response = DARWIN_RESPONSE_SEND_BOTH; + DBGPRINTF("mmdarwin::newActInst:: response type is 'both'\n"); + } + else + { + DBGPRINTF( + "mmdarwin::newActInst:: invalid 'response' value: %s. 'No response' set.\n", + response); + + pData->response = DARWIN_RESPONSE_SEND_NO; + DBGPRINTF("mmdarwin::newActInst:: response type is 'no'\n"); + } + + free(response); + } + else if (!strcmp(actpblk.descr[i].name, "filtercode")) + { + char *filterCode = es_str2cstr(pvals[i].val.d.estr, NULL); + pData->filterCode = strtoull(filterCode, NULL, 16); + free(filterCode); + } + else if (!strcmp(actpblk.descr[i].name, "fields")) + { + pData->fieldList.nmemb = pvals[i].val.d.ar->nmemb; + CHKmalloc(pData->fieldList.name = calloc(pData->fieldList.nmemb, sizeof(char *))); + CHKmalloc(pData->fieldList.varname = calloc(pData->fieldList.nmemb, sizeof(char *))); + + for (int j = 0; j < pData->fieldList.nmemb; ++j) + { + char *const param = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); + char *varname = NULL; + char *name; + if (*param == ':') + { + char *b = strchr(param + 1, ':'); + if (b == NULL) + { + parser_errmsg( + "mmdarwin::newActInst:: missing closing colon: '%s'", param); + ABORT_FINALIZE(RS_RET_ERR); + } + + *b = '\0'; /* split name & varname */ + varname = param + 1; + name = b + 1; + } + else + { + name = param; + } + CHKmalloc(pData->fieldList.name[j] = strdup(name)); + char vnamebuf[1024]; + snprintf(vnamebuf, sizeof(vnamebuf), + "%s!%s", loadModConf->container, + (varname == NULL) ? name : varname); + CHKmalloc(pData->fieldList.varname[j] = strdup(vnamebuf)); + free(param); + DBGPRINTF("mmdarwin::newActInst:: will look for field %s\n", pData->fieldList.name[j]); + } + } + else + { + DBGPRINTF( + "mmdarwin::newActInst:: program error, non-handled param '%s'\n", actpblk.descr[i].name); + } + } + + // reserve space for 'container!key\0' + size_t sizeKey = strlen(loadModConf->container) + strlen(JSON_DARWIN_ID) + 2; + pData->pUUIDKey = malloc(sizeKey); + snprintf(pData->pUUIDKey, sizeKey, "%s!%s", loadModConf->container, JSON_DARWIN_ID); + DBGPRINTF("mmdarwin:: uuid key is %s\n", pData->pUUIDKey); + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + +BEGINtryResume +CODESTARTtryResume + iRet = doTryResume(pWrkrData); +ENDtryResume + +BEGINdoAction_NoStrings + smsg_t **ppMsg = (smsg_t **)pMsgData; /* the raw data */ + smsg_t *pMsg = ppMsg[0]; /* the raw log line */ + instanceData *pData = pWrkrData->pData; /* the parameters given for the plugin */ + char *pFieldValue = NULL; /* ponter to the found field value */ + int fieldsNum = 0; /* number of fields retrieved */ + +CODESTARTdoAction + DBGPRINTF("mmdarwin::doAction:: beggining action\n"); + pWrkrData->darwinBody.bufferMsgSize = 0; + fieldsNum = 0; + + for (int i = 0; i < pData->fieldList.nmemb; i++) + { + DBGPRINTF("mmdarwin::doAction:: processing field '%s'\n", pData->fieldList.name[i]); + pFieldValue = NULL; + + /* case 1: static field. We simply forward it to Darwin */ + if (pData->fieldList.name[i][0] != '!' && pData->fieldList.name[i][0] != '.') + { + pFieldValue = strdup(pData->fieldList.name[i]); + } + /* case 2: dynamic field. We retrieve its value from the JSON logline and forward it to + * Darwin */ + else + { + if (!get_field(pMsg, pData->fieldList.name[i], &pFieldValue)) + { + DBGPRINTF("mmdarwin::doAction:: \ +could not extract field '%s' from message\n", pData->fieldList.name[i]); + continue; + } + } + + DBGPRINTF( + "mmdarwin::doAction:: got value of field '%s': '%s'\n", pData->fieldList.name[i], pFieldValue); + + if (add_field_to_body(&(pWrkrData->darwinBody), pFieldValue, strlen(pFieldValue)) != 0) + { + DBGPRINTF("mmdarwin::doAction:: could not add field to body, aborting\n"); + free(pFieldValue); + ABORT_FINALIZE(RS_RET_ERR); + } + + fieldsNum++; + free(pFieldValue); + } + + if (fieldsNum) + { + if (!pData->sendPartial && fieldsNum != pData->fieldList.nmemb) + { + DBGPRINTF("mmdarwin::doAction:: not all fields could be retrieved, not sending partial message." + " (if you wish to send partial messages anyway, set 'send_partial' to 'on' in instance parameters)\n"); + FINALIZE; + } + if (end_body(&(pWrkrData->darwinBody)) != 0) + ABORT_FINALIZE(RS_RET_ERR); + } + else + { + DBGPRINTF("mmdarwin::doAction:: no fields retrieved, finalizing\n"); + FINALIZE; + } + + DBGPRINTF("mmdarwin::doAction:: body to send: '%s'\n", pWrkrData->darwinBody.buffer); + + if (pData->socketMaxUse) + { + /* need to rotate socket connections */ + if (!pWrkrData->pktSentSocket) + { + DBGPRINTF("mmdarwin::doAction:: opening a new connection\n"); + CHKiRet(doTryResume(pWrkrData)); + } + pWrkrData->pktSentSocket = (pWrkrData->pktSentSocket + 1) % pData->socketMaxUse; + } + + /* the Darwin header to be sent to the filter */ + darwin_filter_packet_t header = { + .type = DARWIN_PACKET_OTHER, + .response = pData->response, + .filter_code = pData->filterCode, + .body_size = pWrkrData->darwinBody.bufferMsgSize}; + + const char *uuid = get_uuid_object(pMsg); + if(uuid) { + DBGPRINTF("mmdarwin: using existing UUID = %s\n", uuid); + if(uuid_parse(uuid, header.evt_id)) + LogError(0, RS_RET_ERR, "mmdarwin:: failed to parse existing UUID: %s\n", uuid); + free((void*)uuid); + } + else { + uuid_generate(header.evt_id); + char uuidStr[40]; + uuid_unparse(header.evt_id, uuidStr); + DBGPRINTF("mmdarwin: generated new UUID = %s\n", uuidStr); + msgAddJSON(pMsg, (uchar *)pData->pUUIDKey, json_object_new_string(uuidStr), 0, 0); + } + + DBGPRINTF("mmdarwin::doAction:: sending header to Darwin\n"); + CHKiRet(sendMsg(pWrkrData, &header, sizeof(darwin_filter_packet_t))); + + DBGPRINTF("mmdarwin::doAction:: sending body to Darwin\n"); + CHKiRet(sendMsg(pWrkrData, (void *)(pWrkrData->darwinBody.buffer), pWrkrData->darwinBody.bufferMsgSize)); + + /* there is no need to wait for a response that will never come */ + if (pData->response == DARWIN_RESPONSE_SEND_NO || pData->response == DARWIN_RESPONSE_SEND_DARWIN) + { + DBGPRINTF("mmdarwin::doAction:: no response will be sent back " + "(darwin response type is set to 'no' or 'darwin')\n"); + goto finalize_it; + } + + darwin_filter_packet_t response; + memset(&response, 0, sizeof(response)); + DBGPRINTF("mmdarwin::doAction:: receiving from Darwin\n"); + CHKiRet(receiveMsg(pWrkrData, &response, sizeof(response))); + + unsigned int certitude = response.certitude_list[0]; + DBGPRINTF("mmdarwin::doAction:: end of the transaction, certitude is %d\n", certitude); + + msgAddJSON(pMsg, (uchar *)pData->pCertitudeKey, json_object_new_int(certitude), 0, 0); + +finalize_it : + DBGPRINTF("mmdarwin::doAction:: finished processing log line\n"); + +ENDdoAction + +NO_LEGACY_CONF_parseSelectorAct + +BEGINmodExit +CODESTARTmodExit + objRelease(glbl, CORE_COMPONENT); +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + /* we only support the current interface specification */ + *ipIFVersProvided = CURR_MOD_IF_VERSION; +CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmdarwin::modInit:: module compiled with rsyslog version %s.\n", VERSION); + CHKiRet(objUse(glbl, CORE_COMPONENT)); +ENDmodInit diff --git a/contrib/mmdarwin/protocol.h b/contrib/mmdarwin/protocol.h new file mode 100644 index 0000000..fce211f --- /dev/null +++ b/contrib/mmdarwin/protocol.h @@ -0,0 +1,70 @@ +/* Copyright 2019 Advens + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef DARWIN_PROTOCOL_H +#define DARWIN_PROTOCOL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stddef.h> +#include <netinet/in.h> + +#define DARWIN_FILTER_CODE_NO 0x00000000 +// the default certitude list size, which is 1, to allow FMAs (see flexible array members on C99) for both C and C++ +// code +#define DEFAULT_CERTITUDE_LIST_SIZE 1 + + /// Represent the receiver of the results. + /// + /// \enum darwin_response_type + enum darwin_filter_response_type + { + DARWIN_RESPONSE_SEND_NO = 0, //!< Don't send results to anybody. + DARWIN_RESPONSE_SEND_BACK, //!< Send results back to caller. + DARWIN_RESPONSE_SEND_DARWIN, //!< Send results to the next filter. + DARWIN_RESPONSE_SEND_BOTH, //!< Send results to both caller and the next filter. + }; + + /// Represent the type of information sent. + /// + /// \enum darwin_packet_type + enum darwin_packet_type + { + DARWIN_PACKET_OTHER = 0, //!< Information sent by something else. + DARWIN_PACKET_FILTER, //!< Information sent by another filter. + }; + + /// First packet to be sent to a filter. + /// + /// \struct darwin_filter_packet_t + typedef struct + { + enum darwin_packet_type type; //!< The type of information sent. + enum darwin_filter_response_type response; //!< Whom the response will be sent to. + long filter_code; //!< The unique identifier code of a filter. + size_t body_size; //!< The complete size of the the parameters to be sent + unsigned char evt_id[16]; //!< An array containing the event ID + size_t certitude_size; //!< The size of the list containing the certitudes. + unsigned int certitude_list[DEFAULT_CERTITUDE_LIST_SIZE]; + //!< The scores or the certitudes of the module. May be used to pass other info in specific cases. + } darwin_filter_packet_t; + +#ifdef __cplusplus +}; +#endif + +#endif /* !DARWIN_PROTOCOL_H */ diff --git a/contrib/mmgrok/Makefile.am b/contrib/mmgrok/Makefile.am new file mode 100644 index 0000000..00c1011 --- /dev/null +++ b/contrib/mmgrok/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmgrok.la + +mmgrok_la_SOURCES = mmgrok.c +mmgrok_la_CPPFLAGS = $(GLIB_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmgrok_la_LDFLAGS = -module -avoid-version +mmgrok_la_LIBADD = $(GLIB_LIBS) -lgrok $(LIBFASTJSON_LIBS) + +EXTRA_DIST = diff --git a/contrib/mmgrok/Makefile.in b/contrib/mmgrok/Makefile.in new file mode 100644 index 0000000..596dbfe --- /dev/null +++ b/contrib/mmgrok/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/mmgrok +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +mmgrok_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_mmgrok_la_OBJECTS = mmgrok_la-mmgrok.lo +mmgrok_la_OBJECTS = $(am_mmgrok_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mmgrok_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(mmgrok_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/mmgrok_la-mmgrok.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(mmgrok_la_SOURCES) +DIST_SOURCES = $(mmgrok_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = mmgrok.la +mmgrok_la_SOURCES = mmgrok.c +mmgrok_la_CPPFLAGS = $(GLIB_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmgrok_la_LDFLAGS = -module -avoid-version +mmgrok_la_LIBADD = $(GLIB_LIBS) -lgrok $(LIBFASTJSON_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmgrok/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/mmgrok/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mmgrok.la: $(mmgrok_la_OBJECTS) $(mmgrok_la_DEPENDENCIES) $(EXTRA_mmgrok_la_DEPENDENCIES) + $(AM_V_CCLD)$(mmgrok_la_LINK) -rpath $(pkglibdir) $(mmgrok_la_OBJECTS) $(mmgrok_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmgrok_la-mmgrok.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mmgrok_la-mmgrok.lo: mmgrok.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmgrok_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmgrok_la-mmgrok.lo -MD -MP -MF $(DEPDIR)/mmgrok_la-mmgrok.Tpo -c -o mmgrok_la-mmgrok.lo `test -f 'mmgrok.c' || echo '$(srcdir)/'`mmgrok.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmgrok_la-mmgrok.Tpo $(DEPDIR)/mmgrok_la-mmgrok.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmgrok.c' object='mmgrok_la-mmgrok.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmgrok_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmgrok_la-mmgrok.lo `test -f 'mmgrok.c' || echo '$(srcdir)/'`mmgrok.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/mmgrok_la-mmgrok.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/mmgrok_la-mmgrok.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/mmgrok/README b/contrib/mmgrok/README new file mode 100644 index 0000000..1194212 --- /dev/null +++ b/contrib/mmgrok/README @@ -0,0 +1,32 @@ +Grok Message Modify Plugin + +Using hundreds of grok patterns from logstash-patterns-core. + +Build + +This plugin requires libfastjson (always present in rsyslog core), glib2, and grok packages. + +If you use RH/CentOS/Fedora, you'll have to build grok rpms by yourself as follow: + + sudo yum install -y yum-utils rpmdevtools + git clone git@github.com:jordansissel/grok.git + mkdir -p ~/rpmbuild/SPECS/; cp grok/grok.spec.template ~/rpmbuild/SPECS/grok.spec + (mkdir -p ~/rpmbuild/SOURCES/; cd ~/rpmbuild/SOURCES/; spectool -g ../SPECS/grok.spec) + sudo yum-builddep ~/rpmbuild/SPECS/grok.spec + rpmbuild -bb ~/rpmbuild/SPECS/grok.spec + # use yum command instead of rpm, because grok depends on libevent, pcre, tokyocabinet + sudo yum install -y libjson-c-devel glib2-devel ~/rpmbuild/RPMS/x86_64/grok*.rpm + +Example + +module(load="mmgrok") +template(name="tmlp" type="string" string="%$!msg!test%\n") +action(type="mmgrok" patterndir="path/to/yourpatternsDir" match="%{WORD:test}" source="msg" target="!msg") +action(type="omfile" file="path/to/file" template="tmlp") + +Description + +patterndir: path to grok patterns dir, default: /usr/share/grok/patterns/base +match:the pattern used to match message +source: the source message/variable to be matched +target: the root path to write the captured json tree diff --git a/contrib/mmgrok/mmgrok.c b/contrib/mmgrok/mmgrok.c new file mode 100644 index 0000000..340c7ba --- /dev/null +++ b/contrib/mmgrok/mmgrok.c @@ -0,0 +1,418 @@ +/* mmgrok.c + * Grok the message is parsed into a structured json data inside JSON. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <ctype.h> +#include <json.h> +#include <grok.h> +#include <glib.h> +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "dirty.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("mmgrok"); + +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal); + +DEF_OMOD_STATIC_DATA + +typedef struct result_s{ + char *key; + int key_len; + const char *value; + int value_len; + char *type; +}result_t; + +/* config variables */ +typedef struct _instanceData +{ + char *pszPatternDir; + char *pszMatch; + char *pszSource; + char *pszTarget;/* as a json root for store parse json data */ + smsg_t *pmsg; /* store origin messages*/ +}instanceData; + +typedef struct wrkrInstanceData{ + instanceData *pData; +}wrkrInstanceData_t; + +struct modConfData_s{ + rsconf_t *pConf;/* our overall config object */ +}; + +static modConfData_t *loadModConf = NULL; +static modConfData_t *runModConf = NULL; + +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[]={ + {"patterndir",eCmdHdlrString,0}, + {"match",eCmdHdlrString,0}, + {"source",eCmdHdlrString,0}, + {"target",eCmdHdlrString,0}, +}; + +static struct cnfparamblk actpblk = +{ + CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr +}; + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + +BEGINfreeInstance +CODESTARTfreeInstance + free(pData->pszPatternDir); + free(pData->pszMatch); + free(pData->pszSource); + free(pData->pszTarget); +ENDfreeInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + + +static inline void setInstParamDefaults(instanceData *pData) +{ + pData->pszPatternDir= NULL; + pData->pszMatch = NULL; + pData->pszSource = NULL; + pData->pszTarget = NULL; + pData->pmsg = NULL; +} + + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; +CODESTARTnewActInst + DBGPRINTF("newActInst (mmgrok)\n"); + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CODE_STD_STRING_REQUESTnewActInst(1) + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(actpblk.descr[i].name, "patterndir")) { + pData->pszPatternDir= es_str2cstr(pvals[i].val.d.estr, NULL); + continue; + } + else if(!strcmp(actpblk.descr[i].name, "match")) { + pData->pszMatch = es_str2cstr(pvals[i].val.d.estr, NULL); + continue; + } + else if(!strcmp(actpblk.descr[i].name, "source")) { + pData->pszSource= es_str2cstr(pvals[i].val.d.estr, NULL); + continue; + } + else if(!strcmp(actpblk.descr[i].name,"target")) + { + pData->pszTarget=es_str2cstr(pvals[i].val.d.estr,NULL); + continue; + } + else{ + DBGPRINTF("mmgrok: program error, non-handled " + "param '%s'\n", actpblk.descr[i].name); + } + } + if(pData->pszTarget == NULL) { + CHKmalloc(pData->pszTarget = strdup("!")); + } +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + DBGPRINTF("mmgrok\n"); +ENDdbgPrintInstInfo + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +static inline grok_t *CreateGrok(void) +{ + grok_t *grok = grok_new(); + if(grok == NULL){ + DBGPRINTF("mmgrok: create a grok faile!"); + exit(1); + } + grok_init(grok); + return grok; +} + +/* the parseing is complate message into json */ +static rsRetVal +smsg_to_json(GList *list,instanceData *pData) +{ + GList *it= list; + + struct json_object *json; + struct json_object *jval; + + DEFiRet; + + json = json_object_new_object(); + if(json == NULL) + { + ABORT_FINALIZE(RS_RET_ERR); + } + for(;it;it= it->next) + { + int key_len = ((result_t *)it->data)->key_len; + char *key = (char *)malloc(key_len+1); + snprintf(key,key_len+1,"%.*s",key_len,((result_t *)it->data)->key); + int value_len = ((result_t *)it->data)->value_len; + char *value = (char *)malloc(value_len+1); + snprintf(value,value_len+1,"%.*s",value_len,((result_t*)it->data)->value); + jval = json_object_new_string(value); + json_object_object_add(json,key,jval); + free(key); + free(value); + } + msgAddJSON(pData->pmsg,(uchar*)pData->pszTarget,json,0,0); +finalize_it: + RETiRet; +} + +/* store parse result ,use list in glib*/ +static rsRetVal +parse_result_store(const grok_match_t gm,instanceData *pData) +{ + GList *re_list = NULL; + char *pname; + const char *pdata; + int pname_len,pdata_len; + + char *key; + char *type; + DEFiRet; + + grok_match_walk_init(&gm); //grok API + + while(grok_match_walk_next(&gm,&pname,&pname_len,&pdata,&pdata_len) == 0) { + /* parse key and value type from patterns */ + key = strchr(pname,':'); + + if(key!=NULL) { + int key_len; + result_t *result = g_new0(result_t,1); + key_len = pname_len - ((key+1) - pname); + key = key+1; + pname_len = key_len; + type = strchr(key,':'); + int type_len; + if(type != NULL) { + key_len = (type - key); + type = type+1; + type_len = pname_len - key_len -1; + type[type_len] = '\0'; + } else { + type = (char*)"null"; + } + /* store parse result into list */ + result->key = key; + result->key_len = key_len; + result->value = pdata; + result->value_len = pdata_len; + result->type = type; + /* the value of merger the same key*/ + re_list = g_list_append(re_list,result); + } + } + smsg_to_json(re_list,pData); + g_list_free(re_list); + grok_match_walk_end(&gm); + RETiRet; +} + +/* motify message for per line */ +static rsRetVal +MotifyLine(char *line,grok_t *grok,instanceData *pData) +{ + grok_match_t gm; + DEFiRet; + grok_patterns_import_from_file(grok,pData->pszPatternDir); + int compile = grok_compile(grok,pData->pszMatch); + if(compile!=GROK_OK) + { + DBGPRINTF("mmgrok: grok_compile faile!exit code: %d\n",compile); + ABORT_FINALIZE(RS_RET_ERR); + } + int exe = grok_exec(grok,line,&gm); + if(exe!=GROK_OK) + { + DBGPRINTF("mmgrok: grok_exec faile!exit code: %d\n",exe); + ABORT_FINALIZE(RS_RET_ERR); + } + parse_result_store(gm,pData); +finalize_it: + RETiRet; +} + +/* motify rsyslog messages */ +static rsRetVal +MotifyMessage(instanceData *pData) +{ + char *saveptr = NULL; + DEFiRet; + grok_t *grok = CreateGrok(); + char *msg = strdup(pData->pszSource); + char *line = NULL; + line = strtok_r(msg, "\n", &saveptr); + while(line!=NULL) { + MotifyLine(line,grok,pData); + line = strtok_r(NULL, "\n", &saveptr); + } + free(msg);msg=NULL; + RETiRet; +} + + +BEGINdoAction_NoStrings + smsg_t **ppMsg = (smsg_t **) pMsgData; + smsg_t *pMsg = ppMsg[0]; + uchar *buf; + instanceData *pData; + +CODESTARTdoAction + pData = pWrkrData->pData; + buf = getMSG(pMsg); + pData->pmsg = pMsg; + while(*buf && isspace(*buf)) { + ++buf; + } + + if(*buf == '\0' ) { + DBGPRINTF("mmgrok: not msg for mmgrok!"); + ABORT_FINALIZE(RS_RET_NO_CEE_MSG); + } + pData->pszSource = (char *)buf; + CHKiRet(MotifyMessage(pData)); + +finalize_it: +ENDdoAction + +BEGINparseSelectorAct +CODESTARTparseSelectorAct +CODE_STD_STRING_REQUESTparseSelectorAct(1) + if(strncmp((char*) p, ":mmgrok:", sizeof(":mmgrok:") - 1)) { + ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); + } + + p += sizeof(":mmgrok:") - 1; /* eat indicator sequence (-1 because of '\0'!) */ + CHKiRet(createInstance(&pData)); + + if(*(p-1) == ';') + --p; + CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_TPL_AS_MSG, (uchar*) "RSYSLOG_FileFormat")); +CODE_STD_FINALIZERparseSelectorAct +ENDparseSelectorAct + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +ENDqueryEtryPt + +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + DEFiRet; + RETiRet; +} + +BEGINmodInit() + rsRetVal localRet; + rsRetVal (*pomsrGetSupportedTplOpts)(unsigned long *pOpts); + unsigned long opts; + int bMsgPassingSupported; +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; +CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmgrok: module compiled with rsyslog version %s.\n", VERSION); + bMsgPassingSupported = 0; + localRet = pHostQueryEtryPt((uchar*)"OMSRgetSupportedTplOpts", + &pomsrGetSupportedTplOpts); + if(localRet == RS_RET_OK) { + CHKiRet((*pomsrGetSupportedTplOpts)(&opts)); + if(opts & OMSR_TPL_AS_MSG) + bMsgPassingSupported = 1; + } else if(localRet != RS_RET_ENTRY_POINT_NOT_FOUND) { + ABORT_FINALIZE(localRet); /* Something else went wrong, not acceptable */ + } + + if(!bMsgPassingSupported) { + DBGPRINTF("mmgrok: msg-passing is not supported by rsyslog core, " + "can not continue.\n"); + ABORT_FINALIZE(RS_RET_NO_MSG_PASSING); + } + + + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); +ENDmodInit diff --git a/contrib/mmkubernetes/Makefile.am b/contrib/mmkubernetes/Makefile.am new file mode 100644 index 0000000..88dca48 --- /dev/null +++ b/contrib/mmkubernetes/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmkubernetes.la + +mmkubernetes_la_SOURCES = mmkubernetes.c +mmkubernetes_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBLOGNORM_CFLAGS) +mmkubernetes_la_LDFLAGS = -module -avoid-version +mmkubernetes_la_LIBADD = $(CURL_LIBS) $(LIBLOGNORM_LIBS) + +EXTRA_DIST = k8s_filename.rulebase k8s_container_name.rulebase diff --git a/contrib/mmkubernetes/Makefile.in b/contrib/mmkubernetes/Makefile.in new file mode 100644 index 0000000..983a32f --- /dev/null +++ b/contrib/mmkubernetes/Makefile.in @@ -0,0 +1,800 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/mmkubernetes +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +mmkubernetes_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_mmkubernetes_la_OBJECTS = mmkubernetes_la-mmkubernetes.lo +mmkubernetes_la_OBJECTS = $(am_mmkubernetes_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mmkubernetes_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(mmkubernetes_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(mmkubernetes_la_SOURCES) +DIST_SOURCES = $(mmkubernetes_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = mmkubernetes.la +mmkubernetes_la_SOURCES = mmkubernetes.c +mmkubernetes_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBLOGNORM_CFLAGS) +mmkubernetes_la_LDFLAGS = -module -avoid-version +mmkubernetes_la_LIBADD = $(CURL_LIBS) $(LIBLOGNORM_LIBS) +EXTRA_DIST = k8s_filename.rulebase k8s_container_name.rulebase +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmkubernetes/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/mmkubernetes/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mmkubernetes.la: $(mmkubernetes_la_OBJECTS) $(mmkubernetes_la_DEPENDENCIES) $(EXTRA_mmkubernetes_la_DEPENDENCIES) + $(AM_V_CCLD)$(mmkubernetes_la_LINK) -rpath $(pkglibdir) $(mmkubernetes_la_OBJECTS) $(mmkubernetes_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mmkubernetes_la-mmkubernetes.lo: mmkubernetes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmkubernetes_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmkubernetes_la-mmkubernetes.lo -MD -MP -MF $(DEPDIR)/mmkubernetes_la-mmkubernetes.Tpo -c -o mmkubernetes_la-mmkubernetes.lo `test -f 'mmkubernetes.c' || echo '$(srcdir)/'`mmkubernetes.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmkubernetes_la-mmkubernetes.Tpo $(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmkubernetes.c' object='mmkubernetes_la-mmkubernetes.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmkubernetes_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmkubernetes_la-mmkubernetes.lo `test -f 'mmkubernetes.c' || echo '$(srcdir)/'`mmkubernetes.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/mmkubernetes/k8s_container_name.rulebase b/contrib/mmkubernetes/k8s_container_name.rulebase new file mode 100644 index 0000000..1fe7373 --- /dev/null +++ b/contrib/mmkubernetes/k8s_container_name.rulebase @@ -0,0 +1,3 @@ +version=2 +rule=:%k8s_prefix:char-to:_%_%container_name:char-to:.%.%container_hash:char-to:_%_%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest% +rule=:%k8s_prefix:char-to:_%_%container_name:char-to:_%_%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest% diff --git a/contrib/mmkubernetes/k8s_filename.rulebase b/contrib/mmkubernetes/k8s_filename.rulebase new file mode 100644 index 0000000..a7b2cac --- /dev/null +++ b/contrib/mmkubernetes/k8s_filename.rulebase @@ -0,0 +1,2 @@ +version=2 +rule=:/var/log/containers/%pod_name:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log diff --git a/contrib/mmkubernetes/mmkubernetes.c b/contrib/mmkubernetes/mmkubernetes.c new file mode 100644 index 0000000..525962e --- /dev/null +++ b/contrib/mmkubernetes/mmkubernetes.c @@ -0,0 +1,2085 @@ +/* mmkubernetes.c + * This is a message modification module. It uses metadata obtained + * from the message to query Kubernetes and obtain additional metadata + * relating to the container instance. + * + * Inspired by: + * https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter + * + * NOTE: read comments in module-template.h for details on the calling interface! + * + * Copyright 2016 Red Hat Inc. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* needed for asprintf */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <unistd.h> +#include <sys/stat.h> +#include <libestr.h> +#include <liblognorm.h> +#include <json.h> +#include <curl/curl.h> +#include <curl/easy.h> +#include <pthread.h> +#include "conf.h" +#include "syslogd-types.h" +#include "module-template.h" +#include "errmsg.h" +#include "statsobj.h" +#include "regexp.h" +#include "hashtable.h" +#include "hashtable_itr.h" +#include "srUtils.h" +#include "unicode-helper.h" +#include "datetime.h" + +/* static data */ +MODULE_TYPE_OUTPUT /* this is technically an output plugin */ +MODULE_TYPE_KEEP /* releasing the module would cause a leak through libcurl */ +MODULE_CNFNAME("mmkubernetes") +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(regexp) +DEFobjCurrIf(statsobj) +DEFobjCurrIf(datetime) + +#define HAVE_LOADSAMPLESFROMSTRING 1 +#if defined(NO_LOADSAMPLESFROMSTRING) +#undef HAVE_LOADSAMPLESFROMSTRING +#endif +/* original from fluentd plugin: + * 'var\.log\.containers\.(?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?\ + * (\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace>[^_]+)_\ + * (?<container_name>.+)-(?<docker_id>[a-z0-9]{64})\.log$' + * this is for _tag_ match, not actual filename match - in_tail turns filename + * into a fluentd tag + */ +#define DFLT_FILENAME_LNRULES "rule=:/var/log/containers/%pod_name:char-to:_%_"\ + "%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log" +#define DFLT_FILENAME_RULEBASE "/etc/rsyslog.d/k8s_filename.rulebase" +/* original from fluentd plugin: + * '^(?<name_prefix>[^_]+)_(?<container_name>[^\._]+)\ + * (\.(?<container_hash>[^_]+))?_(?<pod_name>[^_]+)_\ + * (?<namespace>[^_]+)_[^_]+_[^_]+$' + */ +#define DFLT_CONTAINER_LNRULES "rule=:%k8s_prefix:char-to:_%_%container_name:char-to:.%."\ + "%container_hash:char-to:_%_"\ + "%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest%\n"\ + "rule=:%k8s_prefix:char-to:_%_%container_name:char-to:_%_"\ + "%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest%" +#define DFLT_CONTAINER_RULEBASE "/etc/rsyslog.d/k8s_container_name.rulebase" +#define DFLT_SRCMD_PATH "$!metadata!filename" +#define DFLT_DSTMD_PATH "$!" +#define DFLT_DE_DOT 1 /* true */ +#define DFLT_DE_DOT_SEPARATOR "_" +#define DFLT_CONTAINER_NAME "$!CONTAINER_NAME" /* name of variable holding CONTAINER_NAME value */ +#define DFLT_CONTAINER_ID_FULL "$!CONTAINER_ID_FULL" /* name of variable holding CONTAINER_ID_FULL value */ +#define DFLT_KUBERNETES_URL "https://kubernetes.default.svc.cluster.local:443" +#define DFLT_BUSY_RETRY_INTERVAL 5 /* retry every 5 seconds */ +#define DFLT_SSL_PARTIAL_CHAIN 0 /* disallow X509_V_FLAG_PARTIAL_CHAIN by default */ +#define DFLT_CACHE_ENTRY_TTL 3600 /* delete entries from the cache older than 3600 seconds */ +#define DFLT_CACHE_EXPIRE_INTERVAL -1 /* delete all expired entries from the cache every N seconds + -1 disables cache expiration/ttl checking + 0 means - run cache expiration for every record */ + +/* only support setting the partial chain flag on openssl platforms that have the define */ +#if defined(ENABLE_OPENSSL) && defined(X509_V_FLAG_PARTIAL_CHAIN) +#define SUPPORT_SSL_PARTIAL_CHAIN 1 +#endif + +struct cache_entry_s { + time_t ttl; /* when this entry should expire */ + void *data; /* the user data */ +}; + +static struct cache_s { + const uchar *kbUrl; + struct hashtable *mdHt; + struct hashtable *nsHt; + pthread_mutex_t *cacheMtx; + int lastBusyTime; /* when we got the last busy response from kubernetes */ + time_t expirationTime; /* if cache expiration checking is enable, time to check for expiration */ +} **caches; + +typedef struct { + int nmemb; + uchar **patterns; + regex_t *regexps; +} annotation_match_t; + +/* module configuration data */ +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + uchar *kubernetesUrl; /* scheme, host, port, and optional path prefix for Kubernetes API lookups */ + uchar *srcMetadataPath; /* where to get data for kubernetes queries */ + uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */ + uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */ + uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */ + uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */ + sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */ + sbool skipVerifyHost; /* For testing/debugging - skip cert hostname verify (CURLOPT_SSL_VERIFYHOST FALSE) */ + uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */ + uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */ + sbool de_dot; /* If true (default), convert '.' characters in labels & annotations to de_dot_separator */ + uchar *de_dot_separator; /* separator character (default '_') to use for de_dotting */ + size_t de_dot_separator_len; /* length of separator character */ + annotation_match_t annotation_match; /* annotation keys must match these to be included in record */ + char *fnRules; /* lognorm rules for container log filename match */ + uchar *fnRulebase; /* lognorm rulebase filename for container log filename match */ + char *contRules; /* lognorm rules for CONTAINER_NAME value match */ + uchar *contRulebase; /* lognorm rulebase filename for CONTAINER_NAME value match */ + int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */ + sbool sslPartialChain; /* if true, allow using intermediate certs without root certs */ + int cacheEntryTTL; /* delete entries from the cache if they are older than this many seconds */ + int cacheExpireInterval; /* delete all expired entries from the cache every this many seconds */ +}; + +/* action (instance) configuration data */ +typedef struct _instanceData { + uchar *kubernetesUrl; /* scheme, host, port, and optional path prefix for Kubernetes API lookups */ + msgPropDescr_t *srcMetadataDescr; /* where to get data for kubernetes queries */ + uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */ + uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */ + uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */ + uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */ + sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */ + sbool skipVerifyHost; /* For testing/debugging - skip cert hostname verify (CURLOPT_SSL_VERIFYHOST FALSE) */ + uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */ + uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */ + sbool de_dot; /* If true (default), convert '.' characters in labels & annotations to de_dot_separator */ + uchar *de_dot_separator; /* separator character (default '_') to use for de_dotting */ + size_t de_dot_separator_len; /* length of separator character */ + annotation_match_t annotation_match; /* annotation keys must match these to be included in record */ + char *fnRules; /* lognorm rules for container log filename match */ + uchar *fnRulebase; /* lognorm rulebase filename for container log filename match */ + ln_ctx fnCtxln; /**< context to be used for liblognorm */ + char *contRules; /* lognorm rules for CONTAINER_NAME value match */ + uchar *contRulebase; /* lognorm rulebase filename for CONTAINER_NAME value match */ + ln_ctx contCtxln; /**< context to be used for liblognorm */ + msgPropDescr_t *contNameDescr; /* CONTAINER_NAME field */ + msgPropDescr_t *contIdFullDescr; /* CONTAINER_ID_FULL field */ + struct cache_s *cache; + int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */ + sbool sslPartialChain; /* if true, allow using intermediate certs without root certs */ + int cacheEntryTTL; /* delete entries from the cache if they are older than this many seconds */ + int cacheExpireInterval; /* delete all expired entries from the cache every this many seconds */ +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; + CURL *curlCtx; + struct curl_slist *curlHdr; + char *curlRply; + size_t curlRplyLen; + statsobj_t *stats; /* stats for this instance */ + STATSCOUNTER_DEF(k8sRecordSeen, mutK8sRecordSeen); + STATSCOUNTER_DEF(namespaceMetadataSuccess, mutNamespaceMetadataSuccess); + STATSCOUNTER_DEF(namespaceMetadataNotFound, mutNamespaceMetadataNotFound); + STATSCOUNTER_DEF(namespaceMetadataBusy, mutNamespaceMetadataBusy); + STATSCOUNTER_DEF(namespaceMetadataError, mutNamespaceMetadataError); + STATSCOUNTER_DEF(podMetadataSuccess, mutPodMetadataSuccess); + STATSCOUNTER_DEF(podMetadataNotFound, mutPodMetadataNotFound); + STATSCOUNTER_DEF(podMetadataBusy, mutPodMetadataBusy); + STATSCOUNTER_DEF(podMetadataError, mutPodMetadataError); + STATSCOUNTER_DEF(podCacheNumEntries, mutPodCacheNumEntries); + STATSCOUNTER_DEF(namespaceCacheNumEntries, mutNamespaceCacheNumEntries); + STATSCOUNTER_DEF(podCacheHits, mutPodCacheHits); + STATSCOUNTER_DEF(namespaceCacheHits, mutNamespaceCacheHits); + /* cache misses should correspond to metadata success, busy, etc. k8s api calls */ + STATSCOUNTER_DEF(podCacheMisses, mutPodCacheMisses); + STATSCOUNTER_DEF(namespaceCacheMisses, mutNamespaceCacheMisses); +} wrkrInstanceData_t; + +/* module parameters (v6 config format) */ +static struct cnfparamdescr modpdescr[] = { + { "kubernetesurl", eCmdHdlrString, 0 }, + { "srcmetadatapath", eCmdHdlrString, 0 }, + { "dstmetadatapath", eCmdHdlrString, 0 }, + { "tls.cacert", eCmdHdlrString, 0 }, + { "tls.mycert", eCmdHdlrString, 0 }, + { "tls.myprivkey", eCmdHdlrString, 0 }, + { "allowunsignedcerts", eCmdHdlrBinary, 0 }, + { "skipverifyhost", eCmdHdlrBinary, 0 }, + { "token", eCmdHdlrString, 0 }, + { "tokenfile", eCmdHdlrString, 0 }, + { "annotation_match", eCmdHdlrArray, 0 }, + { "de_dot", eCmdHdlrBinary, 0 }, + { "de_dot_separator", eCmdHdlrString, 0 }, + { "filenamerulebase", eCmdHdlrString, 0 }, + { "containerrulebase", eCmdHdlrString, 0 }, + { "busyretryinterval", eCmdHdlrInt, 0 }, + { "sslpartialchain", eCmdHdlrBinary, 0 }, + { "cacheentryttl", eCmdHdlrInt, 0 }, + { "cacheexpireinterval", eCmdHdlrInt, 0 } +#if HAVE_LOADSAMPLESFROMSTRING == 1 + , + { "filenamerules", eCmdHdlrArray, 0 }, + { "containerrules", eCmdHdlrArray, 0 } +#endif +}; +static struct cnfparamblk modpblk = { + CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr +}; + +/* action (instance) parameters (v6 config format) */ +static struct cnfparamdescr actpdescr[] = { + { "kubernetesurl", eCmdHdlrString, 0 }, + { "srcmetadatapath", eCmdHdlrString, 0 }, + { "dstmetadatapath", eCmdHdlrString, 0 }, + { "tls.cacert", eCmdHdlrString, 0 }, + { "tls.mycert", eCmdHdlrString, 0 }, + { "tls.myprivkey", eCmdHdlrString, 0 }, + { "allowunsignedcerts", eCmdHdlrBinary, 0 }, + { "skipverifyhost", eCmdHdlrBinary, 0 }, + { "token", eCmdHdlrString, 0 }, + { "tokenfile", eCmdHdlrString, 0 }, + { "annotation_match", eCmdHdlrArray, 0 }, + { "de_dot", eCmdHdlrBinary, 0 }, + { "de_dot_separator", eCmdHdlrString, 0 }, + { "filenamerulebase", eCmdHdlrString, 0 }, + { "containerrulebase", eCmdHdlrString, 0 }, + { "busyretryinterval", eCmdHdlrInt, 0 }, + { "sslpartialchain", eCmdHdlrBinary, 0 }, + { "cacheentryttl", eCmdHdlrInt, 0 }, + { "cacheexpireinterval", eCmdHdlrInt, 0 } +#if HAVE_LOADSAMPLESFROMSTRING == 1 + , + { "filenamerules", eCmdHdlrArray, 0 }, + { "containerrules", eCmdHdlrArray, 0 } +#endif +}; +static struct cnfparamblk actpblk = + { CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr + }; + +static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ + +static void free_annotationmatch(annotation_match_t *match) { + if (match) { + for(int ii = 0 ; ii < match->nmemb; ++ii) { + if (match->patterns) + free(match->patterns[ii]); + if (match->regexps) + regexp.regfree(&match->regexps[ii]); + } + free(match->patterns); + match->patterns = NULL; + free(match->regexps); + match->regexps = NULL; + match->nmemb = 0; + } +} + +static int init_annotationmatch(annotation_match_t *match, struct cnfarray *ar) { + DEFiRet; + + match->nmemb = ar->nmemb; + CHKmalloc(match->patterns = calloc(sizeof(uchar*), match->nmemb)); + CHKmalloc(match->regexps = calloc(sizeof(regex_t), match->nmemb)); + for(int jj = 0; jj < ar->nmemb; ++jj) { + int rexret = 0; + match->patterns[jj] = (uchar*)es_str2cstr(ar->arr[jj], NULL); + rexret = regexp.regcomp(&match->regexps[jj], + (char *)match->patterns[jj], REG_EXTENDED|REG_NOSUB); + if (0 != rexret) { + char errMsg[512]; + regexp.regerror(rexret, &match->regexps[jj], errMsg, sizeof(errMsg)); + iRet = RS_RET_CONFIG_ERROR; + LogError(0, iRet, + "error: could not compile annotation_match string [%s]" + " into an extended regexp - %d: %s\n", + match->patterns[jj], rexret, errMsg); + break; + } + } +finalize_it: + if (iRet) + free_annotationmatch(match); + RETiRet; +} + +static int copy_annotationmatch(annotation_match_t *src, annotation_match_t *dest) { + DEFiRet; + + dest->nmemb = src->nmemb; + CHKmalloc(dest->patterns = malloc(sizeof(uchar*) * dest->nmemb)); + CHKmalloc(dest->regexps = calloc(sizeof(regex_t), dest->nmemb)); + for(int jj = 0 ; jj < src->nmemb ; ++jj) { + CHKmalloc(dest->patterns[jj] = (uchar*)strdup((char *)src->patterns[jj])); + /* assumes was already successfully compiled */ + regexp.regcomp(&dest->regexps[jj], (char *)dest->patterns[jj], REG_EXTENDED|REG_NOSUB); + } +finalize_it: + if (iRet) + free_annotationmatch(dest); + RETiRet; +} + +/* takes a hash of annotations and returns another json object hash containing only the + * keys that match - this logic is taken directly from fluent-plugin-kubernetes_metadata_filter + * except that we do not add the key multiple times to the object to be returned + */ +static struct json_object *match_annotations(annotation_match_t *match, + struct json_object *annotations) { + struct json_object *ret = NULL; + + for (int jj = 0; jj < match->nmemb; ++jj) { + struct json_object_iterator it = json_object_iter_begin(annotations); + struct json_object_iterator itEnd = json_object_iter_end(annotations); + for (;!json_object_iter_equal(&it, &itEnd); json_object_iter_next(&it)) { + const char *const key = json_object_iter_peek_name(&it); + if (!ret || !fjson_object_object_get_ex(ret, key, NULL)) { + if (!regexp.regexec(&match->regexps[jj], key, 0, NULL, 0)) { + if (!ret) { + ret = json_object_new_object(); + } + json_object_object_add(ret, key, + json_object_get(json_object_iter_peek_value(&it))); + } + } + } + } + return ret; +} + +/* This will take a hash of labels or annotations and will de_dot the keys. + * It will return a brand new hash. AFAICT, there is no safe way to + * iterate over the hash while modifying it in place. + */ +static struct json_object *de_dot_json_object(struct json_object *jobj, + const char *delim, size_t delim_len) { + struct json_object *ret = NULL; + struct json_object_iterator it = json_object_iter_begin(jobj); + struct json_object_iterator itEnd = json_object_iter_end(jobj); + es_str_t *new_es_key = NULL; + DEFiRet; + + ret = json_object_new_object(); + while (!json_object_iter_equal(&it, &itEnd)) { + const char *const key = json_object_iter_peek_name(&it); + const char *cc = strstr(key, "."); + if (NULL == cc) { + json_object_object_add(ret, key, + json_object_get(json_object_iter_peek_value(&it))); + } else { + char *new_key = NULL; + const char *prevcc = key; + new_es_key = es_newStrFromCStr(key, (es_size_t)(cc-prevcc)); + while (cc) { + if (es_addBuf(&new_es_key, (char *)delim, (es_size_t)delim_len)) + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + cc += 1; /* one past . */ + prevcc = cc; /* beginning of next substring */ + if ((cc = strstr(prevcc, ".")) || (cc = strchr(prevcc, '\0'))) { + if (es_addBuf(&new_es_key, (char *)prevcc, (es_size_t)(cc-prevcc))) + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + if (!*cc) + cc = NULL; /* EOS - done */ + } + } + new_key = es_str2cstr(new_es_key, NULL); + es_deleteStr(new_es_key); + new_es_key = NULL; + json_object_object_add(ret, new_key, + json_object_get(json_object_iter_peek_value(&it))); + free(new_key); + } + json_object_iter_next(&it); + } +finalize_it: + if (iRet != RS_RET_OK) { + json_object_put(ret); + ret = NULL; + } + if (new_es_key) + es_deleteStr(new_es_key); + return ret; +} + +/* given a "metadata" object field, do + * - make sure "annotations" field has only the matching keys + * - de_dot the "labels" and "annotations" fields keys + * This modifies the jMetadata object in place + */ +static void parse_labels_annotations(struct json_object *jMetadata, + annotation_match_t *match, sbool de_dot, + const char *delim, size_t delim_len) { + struct json_object *jo = NULL; + + if (fjson_object_object_get_ex(jMetadata, "annotations", &jo)) { + if ((jo = match_annotations(match, jo))) + json_object_object_add(jMetadata, "annotations", jo); + else + json_object_object_del(jMetadata, "annotations"); + } + /* dedot labels and annotations */ + if (de_dot) { + struct json_object *jo2 = NULL; + if (fjson_object_object_get_ex(jMetadata, "annotations", &jo)) { + if ((jo2 = de_dot_json_object(jo, delim, delim_len))) { + json_object_object_add(jMetadata, "annotations", jo2); + } + } + if (fjson_object_object_get_ex(jMetadata, "labels", &jo)) { + if ((jo2 = de_dot_json_object(jo, delim, delim_len))) { + json_object_object_add(jMetadata, "labels", jo2); + } + } + } +} + +#if HAVE_LOADSAMPLESFROMSTRING == 1 +static int array_to_rules(struct cnfarray *ar, char **rules) { + DEFiRet; + es_str_t *tmpstr = NULL; + es_size_t size = 0; + + if (rules == NULL) + FINALIZE; + *rules = NULL; + if (!ar->nmemb) + FINALIZE; + for (int jj = 0; jj < ar->nmemb; jj++) + size += es_strlen(ar->arr[jj]); + if (!size) + FINALIZE; + CHKmalloc(tmpstr = es_newStr(size)); + CHKiRet((es_addStr(&tmpstr, ar->arr[0]))); + CHKiRet((es_addBufConstcstr(&tmpstr, "\n"))); + for(int jj=1; jj < ar->nmemb; ++jj) { + CHKiRet((es_addStr(&tmpstr, ar->arr[jj]))); + CHKiRet((es_addBufConstcstr(&tmpstr, "\n"))); + } + CHKiRet((es_addBufConstcstr(&tmpstr, "\0"))); + CHKmalloc(*rules = es_str2cstr(tmpstr, NULL)); +finalize_it: + if (tmpstr) { + es_deleteStr(tmpstr); + } + if (iRet != RS_RET_OK) { + free(*rules); + *rules = NULL; + } + RETiRet; +} +#endif + +/* callback for liblognorm error messages */ +static void +errCallBack(void __attribute__((unused)) *cookie, const char *msg, + size_t __attribute__((unused)) lenMsg) +{ + LogError(0, RS_RET_ERR_LIBLOGNORM, "liblognorm error: %s", msg); +} + +static rsRetVal +set_lnctx(ln_ctx *ctxln, char *instRules, uchar *instRulebase, char *modRules, uchar *modRulebase) +{ + DEFiRet; + if (ctxln == NULL) + FINALIZE; + CHKmalloc(*ctxln = ln_initCtx()); + ln_setErrMsgCB(*ctxln, errCallBack, NULL); + if(instRules) { +#if HAVE_LOADSAMPLESFROMSTRING == 1 + if(ln_loadSamplesFromString(*ctxln, instRules) !=0) { + LogError(0, RS_RET_NO_RULEBASE, "error: normalization rules '%s' " + "could not be loaded", instRules); + ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); + } +#else + (void)instRules; +#endif + } else if(instRulebase) { + if(ln_loadSamples(*ctxln, (char*) instRulebase) != 0) { + LogError(0, RS_RET_NO_RULEBASE, "error: normalization rulebase '%s' " + "could not be loaded", instRulebase); + ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); + } + } else if(modRules) { +#if HAVE_LOADSAMPLESFROMSTRING == 1 + if(ln_loadSamplesFromString(*ctxln, modRules) !=0) { + LogError(0, RS_RET_NO_RULEBASE, "error: normalization rules '%s' " + "could not be loaded", modRules); + ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); + } +#else + (void)modRules; +#endif + } else if(modRulebase) { + if(ln_loadSamples(*ctxln, (char*) modRulebase) != 0) { + LogError(0, RS_RET_NO_RULEBASE, "error: normalization rulebase '%s' " + "could not be loaded", modRulebase); + ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); + } + } +finalize_it: + if (iRet != RS_RET_OK){ + ln_exitCtx(*ctxln); + *ctxln = NULL; + } + RETiRet; +} + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; + FILE *fp = NULL; + int ret; + char errStr[1024]; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "mmkubernetes: " + "error processing module config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for mmkubernetes:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + loadModConf->de_dot = DFLT_DE_DOT; + loadModConf->busyRetryInterval = DFLT_BUSY_RETRY_INTERVAL; + loadModConf->sslPartialChain = DFLT_SSL_PARTIAL_CHAIN; + loadModConf->cacheEntryTTL = DFLT_CACHE_ENTRY_TTL; + loadModConf->cacheExpireInterval = DFLT_CACHE_EXPIRE_INTERVAL; + for(i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) { + continue; + } else if(!strcmp(modpblk.descr[i].name, "kubernetesurl")) { + free(loadModConf->kubernetesUrl); + loadModConf->kubernetesUrl = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "srcmetadatapath")) { + free(loadModConf->srcMetadataPath); + loadModConf->srcMetadataPath = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + /* todo: sanitize the path */ + } else if(!strcmp(modpblk.descr[i].name, "dstmetadatapath")) { + free(loadModConf->dstMetadataPath); + loadModConf->dstMetadataPath = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + /* todo: sanitize the path */ + } else if(!strcmp(modpblk.descr[i].name, "tls.cacert")) { + free(loadModConf->caCertFile); + loadModConf->caCertFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)loadModConf->caCertFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: 'tls.cacert' file %s couldn't be accessed: %s\n", + loadModConf->caCertFile, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(modpblk.descr[i].name, "tls.mycert")) { + free(loadModConf->myCertFile); + loadModConf->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)loadModConf->myCertFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: 'tls.mycert' file %s couldn't be accessed: %s\n", + loadModConf->myCertFile, errStr); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(modpblk.descr[i].name, "tls.myprivkey")) { + loadModConf->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)loadModConf->myPrivKeyFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n", + loadModConf->myPrivKeyFile, errStr); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(modpblk.descr[i].name, "allowunsignedcerts")) { + loadModConf->allowUnsignedCerts = pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "skipverifyhost")) { + loadModConf->skipVerifyHost = pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "token")) { + free(loadModConf->token); + loadModConf->token = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "tokenfile")) { + free(loadModConf->tokenFile); + loadModConf->tokenFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)loadModConf->tokenFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: token file %s couldn't be accessed: %s\n", + loadModConf->tokenFile, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(modpblk.descr[i].name, "annotation_match")) { + free_annotationmatch(&loadModConf->annotation_match); + if ((ret = init_annotationmatch(&loadModConf->annotation_match, pvals[i].val.d.ar))) + ABORT_FINALIZE(ret); + } else if(!strcmp(modpblk.descr[i].name, "de_dot")) { + loadModConf->de_dot = pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "de_dot_separator")) { + free(loadModConf->de_dot_separator); + loadModConf->de_dot_separator = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); +#if HAVE_LOADSAMPLESFROMSTRING == 1 + } else if(!strcmp(modpblk.descr[i].name, "filenamerules")) { + free(loadModConf->fnRules); + CHKiRet((array_to_rules(pvals[i].val.d.ar, &loadModConf->fnRules))); +#endif + } else if(!strcmp(modpblk.descr[i].name, "filenamerulebase")) { + free(loadModConf->fnRulebase); + loadModConf->fnRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)loadModConf->fnRulebase, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: filenamerulebase file %s couldn't be accessed: %s\n", + loadModConf->fnRulebase, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } +#if HAVE_LOADSAMPLESFROMSTRING == 1 + } else if(!strcmp(modpblk.descr[i].name, "containerrules")) { + free(loadModConf->contRules); + CHKiRet((array_to_rules(pvals[i].val.d.ar, &loadModConf->contRules))); +#endif + } else if(!strcmp(modpblk.descr[i].name, "containerrulebase")) { + free(loadModConf->contRulebase); + loadModConf->contRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)loadModConf->contRulebase, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: containerrulebase file %s couldn't be accessed: %s\n", + loadModConf->contRulebase, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(modpblk.descr[i].name, "busyretryinterval")) { + loadModConf->busyRetryInterval = pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "sslpartialchain")) { +#if defined(SUPPORT_SSL_PARTIAL_CHAIN) + loadModConf->sslPartialChain = pvals[i].val.d.n; +#else + LogMsg(0, RS_RET_VALUE_NOT_IN_THIS_MODE, LOG_INFO, + "sslpartialchain is only supported for OpenSSL\n"); +#endif + } else if(!strcmp(modpblk.descr[i].name, "cacheentryttl")) { + loadModConf->cacheEntryTTL = pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "cacheexpireinterval")) { + loadModConf->cacheExpireInterval = pvals[i].val.d.n; + } else { + dbgprintf("mmkubernetes: program error, non-handled " + "param '%s' in module() block\n", modpblk.descr[i].name); + /* todo: error message? */ + } + } + +#if HAVE_LOADSAMPLESFROMSTRING == 1 + if (loadModConf->fnRules && loadModConf->fnRulebase) { + LogError(0, RS_RET_CONFIG_ERROR, + "mmkubernetes: only 1 of filenamerules or filenamerulebase may be used"); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + if (loadModConf->contRules && loadModConf->contRulebase) { + LogError(0, RS_RET_CONFIG_ERROR, + "mmkubernetes: only 1 of containerrules or containerrulebase may be used"); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } +#endif + + if ((loadModConf->cacheExpireInterval > -1)) { + if ((loadModConf->cacheEntryTTL < 0)) { + LogError(0, RS_RET_CONFIG_ERROR, + "mmkubernetes: cacheentryttl value [%d] is invalid - " + "value must be 0 or greater", + loadModConf->cacheEntryTTL); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + } + + /* set defaults */ + if(loadModConf->srcMetadataPath == NULL) + loadModConf->srcMetadataPath = (uchar *) strdup(DFLT_SRCMD_PATH); + if(loadModConf->dstMetadataPath == NULL) + loadModConf->dstMetadataPath = (uchar *) strdup(DFLT_DSTMD_PATH); + if(loadModConf->de_dot_separator == NULL) + loadModConf->de_dot_separator = (uchar *) strdup(DFLT_DE_DOT_SEPARATOR); + if(loadModConf->de_dot_separator) + loadModConf->de_dot_separator_len = strlen((const char *)loadModConf->de_dot_separator); +#if HAVE_LOADSAMPLESFROMSTRING == 1 + if (loadModConf->fnRules == NULL && loadModConf->fnRulebase == NULL) + loadModConf->fnRules = strdup(DFLT_FILENAME_LNRULES); + if (loadModConf->contRules == NULL && loadModConf->contRulebase == NULL) + loadModConf->contRules = strdup(DFLT_CONTAINER_LNRULES); +#else + if (loadModConf->fnRulebase == NULL) + loadModConf->fnRulebase = (uchar *)strdup(DFLT_FILENAME_RULEBASE); + if (loadModConf->contRulebase == NULL) + loadModConf->contRulebase = (uchar *)strdup(DFLT_CONTAINER_RULEBASE); +#endif + caches = calloc(1, sizeof(struct cache_s *)); + +finalize_it: + if (fp) + fclose(fp); + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + + +BEGINfreeInstance +CODESTARTfreeInstance + free(pData->kubernetesUrl); + msgPropDescrDestruct(pData->srcMetadataDescr); + free(pData->srcMetadataDescr); + free(pData->dstMetadataPath); + free(pData->caCertFile); + free(pData->myCertFile); + free(pData->myPrivKeyFile); + free(pData->token); + free(pData->tokenFile); + free(pData->fnRules); + free(pData->fnRulebase); + ln_exitCtx(pData->fnCtxln); + free(pData->contRules); + free(pData->contRulebase); + ln_exitCtx(pData->contCtxln); + free_annotationmatch(&pData->annotation_match); + free(pData->de_dot_separator); + msgPropDescrDestruct(pData->contNameDescr); + free(pData->contNameDescr); + msgPropDescrDestruct(pData->contIdFullDescr); + free(pData->contIdFullDescr); +ENDfreeInstance + +static size_t curlCB(char *data, size_t size, size_t nmemb, void *usrptr) +{ + DEFiRet; + wrkrInstanceData_t *pWrkrData = (wrkrInstanceData_t *) usrptr; + char * buf; + size_t newlen; + + newlen = pWrkrData->curlRplyLen + size * nmemb; + CHKmalloc(buf = realloc(pWrkrData->curlRply, newlen)); + memcpy(buf + pWrkrData->curlRplyLen, data, size * nmemb); + pWrkrData->curlRply = buf; + pWrkrData->curlRplyLen = newlen; + +finalize_it: + if (iRet != RS_RET_OK) { + return 0; + } + return size * nmemb; +} + +#if defined(SUPPORT_SSL_PARTIAL_CHAIN) +static CURLcode set_ssl_partial_chain(CURL *curl, void *ssl_ctx, void *userptr) +{ + (void)userptr; /* currently unused */ + CURLcode rv = CURLE_ABORTED_BY_CALLBACK; + X509_STORE *store = NULL; + + store = SSL_CTX_get_cert_store((SSL_CTX *)ssl_ctx); + if(!store) + goto finalize_it; + if(!X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN)) + goto finalize_it; + rv = CURLE_OK; +finalize_it: + return rv; +} +#endif + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance + CURL *ctx; + struct curl_slist *hdr = NULL; + char *tokenHdr = NULL; + FILE *fp = NULL; + char *token = NULL; + char *statsName = NULL; + + CHKiRet(statsobj.Construct(&(pWrkrData->stats))); + if ((-1 == asprintf(&statsName, "mmkubernetes(%s)", pWrkrData->pData->kubernetesUrl)) || + (!statsName)) { + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + CHKiRet(statsobj.SetName(pWrkrData->stats, (uchar *)statsName)); + free(statsName); + statsName = NULL; + CHKiRet(statsobj.SetOrigin(pWrkrData->stats, UCHAR_CONSTANT("mmkubernetes"))); + STATSCOUNTER_INIT(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("recordseen"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->k8sRecordSeen))); + STATSCOUNTER_INIT(pWrkrData->namespaceMetadataSuccess, pWrkrData->mutNamespaceMetadataSuccess); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatasuccess"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataSuccess))); + STATSCOUNTER_INIT(pWrkrData->namespaceMetadataNotFound, pWrkrData->mutNamespaceMetadataNotFound); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatanotfound"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataNotFound))); + STATSCOUNTER_INIT(pWrkrData->namespaceMetadataBusy, pWrkrData->mutNamespaceMetadataBusy); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatabusy"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataBusy))); + STATSCOUNTER_INIT(pWrkrData->namespaceMetadataError, pWrkrData->mutNamespaceMetadataError); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadataerror"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataError))); + STATSCOUNTER_INIT(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatasuccess"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataSuccess))); + STATSCOUNTER_INIT(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatanotfound"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataNotFound))); + STATSCOUNTER_INIT(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatabusy"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataBusy))); + STATSCOUNTER_INIT(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadataerror"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataError))); + STATSCOUNTER_INIT(pWrkrData->namespaceCacheNumEntries, pWrkrData->mutNamespaceCacheNumEntries); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacecachenumentries"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceCacheNumEntries))); + STATSCOUNTER_INIT(pWrkrData->podCacheNumEntries, pWrkrData->mutPodCacheNumEntries); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podcachenumentries"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podCacheNumEntries))); + STATSCOUNTER_INIT(pWrkrData->namespaceCacheHits, pWrkrData->mutNamespaceCacheHits); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacecachehits"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceCacheHits))); + STATSCOUNTER_INIT(pWrkrData->podCacheHits, pWrkrData->mutPodCacheHits); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podcachehits"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podCacheHits))); + STATSCOUNTER_INIT(pWrkrData->namespaceCacheMisses, pWrkrData->mutNamespaceCacheMisses); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacecachemisses"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceCacheMisses))); + STATSCOUNTER_INIT(pWrkrData->podCacheMisses, pWrkrData->mutPodCacheMisses); + CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podcachemisses"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podCacheMisses))); + CHKiRet(statsobj.ConstructFinalize(pWrkrData->stats)); + + hdr = curl_slist_append(hdr, "Content-Type: text/json; charset=utf-8"); + if (pWrkrData->pData->token) { + if ((-1 == asprintf(&tokenHdr, "Authorization: Bearer %s", pWrkrData->pData->token)) || + (!tokenHdr)) { + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + } else if (pWrkrData->pData->tokenFile) { + struct stat statbuf; + fp = fopen((const char*)pWrkrData->pData->tokenFile, "r"); + if (fp && !fstat(fileno(fp), &statbuf)) { + size_t bytesread; + CHKmalloc(token = malloc((statbuf.st_size+1)*sizeof(char))); + if (0 < (bytesread = fread(token, sizeof(char), statbuf.st_size, fp))) { + token[bytesread] = '\0'; + if ((-1 == asprintf(&tokenHdr, "Authorization: Bearer %s", token)) || + (!tokenHdr)) { + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + } + free(token); + token = NULL; + } + if (fp) { + fclose(fp); + fp = NULL; + } + } + if (tokenHdr) { + hdr = curl_slist_append(hdr, tokenHdr); + free(tokenHdr); + } + pWrkrData->curlHdr = hdr; + ctx = curl_easy_init(); + curl_easy_setopt(ctx, CURLOPT_HTTPHEADER, hdr); + curl_easy_setopt(ctx, CURLOPT_WRITEFUNCTION, curlCB); + curl_easy_setopt(ctx, CURLOPT_WRITEDATA, pWrkrData); + if(pWrkrData->pData->caCertFile) + curl_easy_setopt(ctx, CURLOPT_CAINFO, pWrkrData->pData->caCertFile); + if(pWrkrData->pData->myCertFile) + curl_easy_setopt(ctx, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile); + if(pWrkrData->pData->myPrivKeyFile) + curl_easy_setopt(ctx, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile); + if(pWrkrData->pData->allowUnsignedCerts) + curl_easy_setopt(ctx, CURLOPT_SSL_VERIFYPEER, 0); + if(pWrkrData->pData->skipVerifyHost) + curl_easy_setopt(ctx, CURLOPT_SSL_VERIFYHOST, 0); +#if defined(SUPPORT_SSL_PARTIAL_CHAIN) + if(pWrkrData->pData->sslPartialChain) { + curl_easy_setopt(ctx, CURLOPT_SSL_CTX_FUNCTION, set_ssl_partial_chain); + curl_easy_setopt(ctx, CURLOPT_SSL_CTX_DATA, NULL); + } +#endif + pWrkrData->curlCtx = ctx; +finalize_it: + free(token); + free(statsName); + if ((iRet != RS_RET_OK) && pWrkrData->stats) { + statsobj.Destruct(&(pWrkrData->stats)); + } + if (fp) { + fclose(fp); + } +ENDcreateWrkrInstance + + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance + curl_easy_cleanup(pWrkrData->curlCtx); + curl_slist_free_all(pWrkrData->curlHdr); + statsobj.Destruct(&(pWrkrData->stats)); +ENDfreeWrkrInstance + + +/* next function is work-around to avoid type-unsafe casts. It looks + * like not really needed in practice, but gcc 8 complains and doing + * it 100% correct for sure does not hurt ;-) -- rgerhards, 2018-07-19 + */ +static void +hashtable_json_object_put(void *jso) +{ + json_object_put((struct fjson_object *)jso); +} + +static void +cache_entry_free(struct cache_entry_s *cache_entry) +{ + if (NULL != cache_entry) { + if (cache_entry->data) { + hashtable_json_object_put(cache_entry->data); + cache_entry->data = NULL; + } + free(cache_entry); + } +} + +static void +cache_entry_free_raw(void *cache_entry_void) +{ + cache_entry_free((struct cache_entry_s *)cache_entry_void); +} + +static struct cache_s * +cacheNew(instanceData *pData) +{ + DEFiRet; + struct cache_s *cache = NULL; + time_t now; + int need_mutex_destroy = 0; + + CHKmalloc(cache = (struct cache_s *)calloc(1, sizeof(struct cache_s))); + CHKmalloc(cache->cacheMtx = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t))); + CHKmalloc(cache->mdHt = create_hashtable(100, hash_from_string, + key_equals_string, cache_entry_free_raw)); + CHKmalloc(cache->nsHt = create_hashtable(100, hash_from_string, + key_equals_string, cache_entry_free_raw)); + CHKiConcCtrl(pthread_mutex_init(cache->cacheMtx, NULL)); + need_mutex_destroy = 1; + datetime.GetTime(&now); + cache->kbUrl = pData->kubernetesUrl; + cache->expirationTime = 0; + if (pData->cacheExpireInterval > -1) + cache->expirationTime = pData->cacheExpireInterval + pData->cacheEntryTTL + now; + cache->lastBusyTime = 0; + dbgprintf("mmkubernetes: created cache mdht [%p] nsht [%p]\n", + cache->mdHt, cache->nsHt); + +finalize_it: + if (iRet != RS_RET_OK) { + LogError(errno, iRet, "mmkubernetes: cacheNew: unable to create metadata cache for %s", + pData->kubernetesUrl); + if (cache) { + if (cache->mdHt) + hashtable_destroy(cache->mdHt, 1); + if (cache->nsHt) + hashtable_destroy(cache->nsHt, 1); + if (cache->cacheMtx) { + if (need_mutex_destroy) + pthread_mutex_destroy(cache->cacheMtx); + free(cache->cacheMtx); + } + free(cache); + cache = NULL; + } + } + return cache; +} + + +static void cacheFree(struct cache_s *cache) +{ + hashtable_destroy(cache->mdHt, 1); + hashtable_destroy(cache->nsHt, 1); + pthread_mutex_destroy(cache->cacheMtx); + free(cache->cacheMtx); + free(cache); +} + +/* must be called with cache->cacheMtx held */ +/* assumes caller has reference to jso (json_object_get or is a new object) */ +static struct cache_entry_s *cache_entry_new(time_t ttl, struct fjson_object *jso) +{ + DEFiRet; + struct cache_entry_s *cache_entry = NULL; + + CHKmalloc(cache_entry = malloc(sizeof(struct cache_entry_s))); + cache_entry->ttl = ttl; + cache_entry->data = (void *)jso; +finalize_it: + if (iRet) { + free(cache_entry); + cache_entry = NULL; + } + return cache_entry; +} + +static int cache_delete_expired_entries(wrkrInstanceData_t *pWrkrData, int isnsmd, time_t now) +{ + struct hashtable *ht = isnsmd ? pWrkrData->pData->cache->nsHt : pWrkrData->pData->cache->mdHt; + struct hashtable_itr *itr = NULL; + int more; + + if ((pWrkrData->pData->cacheExpireInterval < 0) || (now < pWrkrData->pData->cache->expirationTime)) { + return 0; /* not enabled or not time yet */ + } + + /* set next expiration time */ + pWrkrData->pData->cache->expirationTime = now + pWrkrData->pData->cacheExpireInterval; + + if (hashtable_count(ht) < 1) + return 1; /* expire interval hit but nothing to do */ + + itr = hashtable_iterator(ht); + if (NULL == itr) + return 1; /* expire interval hit but nothing to do - err? */ + + do { + struct cache_entry_s *cache_entry = (struct cache_entry_s *)hashtable_iterator_value(itr); + + if (now >= cache_entry->ttl) { + cache_entry_free(cache_entry); + if (isnsmd) { + STATSCOUNTER_DEC(pWrkrData->namespaceCacheNumEntries, + pWrkrData->mutNamespaceCacheNumEntries); + } else { + STATSCOUNTER_DEC(pWrkrData->podCacheNumEntries, + pWrkrData->mutPodCacheNumEntries); + } + more = hashtable_iterator_remove(itr); + } else { + more = hashtable_iterator_advance(itr); + } + } while (more); + free(itr); + dbgprintf("mmkubernetes: cache_delete_expired_entries: cleaned [%s] cache - size is now [%llu]\n", + isnsmd ? "namespace" : "pod", + isnsmd ? pWrkrData->namespaceCacheNumEntries : pWrkrData->podCacheNumEntries); + return 1; +} + +/* must be called with cache->cacheMtx held */ +static struct fjson_object * +cache_entry_get(wrkrInstanceData_t *pWrkrData, + int isnsmd, const char *key, time_t now) +{ + struct fjson_object *jso = NULL; + struct cache_entry_s *cache_entry = NULL; + int checkttl = 1; + struct hashtable *ht = isnsmd ? pWrkrData->pData->cache->nsHt : pWrkrData->pData->cache->mdHt; + + /* see if it is time for a general cache expiration */ + if (cache_delete_expired_entries(pWrkrData, isnsmd, now)) + checkttl = 0; /* no need to check ttl now */ + cache_entry = (struct cache_entry_s *)hashtable_search(ht, (void *)key); + if (cache_entry && checkttl && (now >= cache_entry->ttl)) { + cache_entry = (struct cache_entry_s *)hashtable_remove(ht, (void *)key); + if (isnsmd) { + STATSCOUNTER_DEC(pWrkrData->namespaceCacheNumEntries, + pWrkrData->mutNamespaceCacheNumEntries); + } else { + STATSCOUNTER_DEC(pWrkrData->podCacheNumEntries, + pWrkrData->mutPodCacheNumEntries); + } + cache_entry_free(cache_entry); + cache_entry = NULL; + } + if (cache_entry) { + jso = (struct fjson_object *)cache_entry->data; + if (isnsmd) { + STATSCOUNTER_INC(pWrkrData->namespaceCacheHits, + pWrkrData->mutNamespaceCacheHits); + } else { + STATSCOUNTER_INC(pWrkrData->podCacheHits, + pWrkrData->mutPodCacheHits); + } + dbgprintf("mmkubernetes: cache_entry_get: cache hit for [%s] cache key [%s] - hits is now [%llu]\n", + isnsmd ? "namespace" : "pod", key, + isnsmd ? pWrkrData->namespaceCacheHits : pWrkrData->podCacheHits); + } else { + if (isnsmd) { + STATSCOUNTER_INC(pWrkrData->namespaceCacheMisses, + pWrkrData->mutNamespaceCacheMisses); + } else { + STATSCOUNTER_INC(pWrkrData->podCacheMisses, + pWrkrData->mutPodCacheMisses); + } + dbgprintf("mmkubernetes: cache_entry_get: cache miss for [%s] cache key [%s] - misses is now [%llu]\n", + isnsmd ? "namespace" : "pod", key, + isnsmd ? pWrkrData->namespaceCacheMisses : pWrkrData->podCacheMisses); + } + + return jso; +} + +/* must be called with cache->cacheMtx held */ +/* key is passed in - caller must copy or otherwise ensure it is ok to pass off + * ownership + */ +static rsRetVal +cache_entry_add(wrkrInstanceData_t *pWrkrData, + int isnsmd, const char *key, struct fjson_object *jso, time_t now, const int bDupKey) +{ + DEFiRet; + struct cache_entry_s *cache_entry = NULL; + struct hashtable *ht = isnsmd ? pWrkrData->pData->cache->nsHt : pWrkrData->pData->cache->mdHt; + + /* see if it is time for a general cache expiration */ + (void)cache_delete_expired_entries(pWrkrData, isnsmd, now); + CHKmalloc(cache_entry = cache_entry_new(now + pWrkrData->pData->cacheEntryTTL, jso)); + if (cache_entry) { + if (!hashtable_insert(ht, (void *)(bDupKey ? strdup(key) : key), cache_entry)) + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + + if (isnsmd) { + STATSCOUNTER_INC(pWrkrData->namespaceCacheNumEntries, + pWrkrData->mutNamespaceCacheNumEntries); + } else { + STATSCOUNTER_INC(pWrkrData->podCacheNumEntries, + pWrkrData->mutPodCacheNumEntries); + } + cache_entry = NULL; + } +finalize_it: + if (cache_entry) + cache_entry_free(cache_entry); + return iRet; +} + +/* must be called with cache->cacheMtx held */ +static struct fjson_object *cache_entry_get_md(wrkrInstanceData_t *pWrkrData, const char *key, time_t now) +{ + return cache_entry_get(pWrkrData, 0, key, now); +} + +/* must be called with cache->cacheMtx held */ +static struct fjson_object *cache_entry_get_nsmd(wrkrInstanceData_t *pWrkrData, const char *key, time_t now) +{ + return cache_entry_get(pWrkrData, 1, key, now); +} + +/* must be called with cache->cacheMtx held */ +static rsRetVal cache_entry_add_md(wrkrInstanceData_t *pWrkrData, const char *key, + struct fjson_object *jso, time_t now) +{ + return cache_entry_add(pWrkrData, 0, key, jso, now, 0); +} + +/* must be called with cache->cacheMtx held */ +static rsRetVal cache_entry_add_nsmd(wrkrInstanceData_t *pWrkrData, const char *key, + struct fjson_object *jso, time_t now) +{ + return cache_entry_add(pWrkrData, 1, key, jso, now, 1); +} + + +BEGINnewActInst + struct cnfparamvals *pvals = NULL; + int i; + FILE *fp = NULL; + char *rxstr = NULL; + char *srcMetadataPath = NULL; + char errStr[1024]; +CODESTARTnewActInst + DBGPRINTF("newActInst (mmkubernetes)\n"); + + pvals = nvlstGetParams(lst, &actpblk, NULL); + if(pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "mmkubernetes: " + "error processing config parameters [action(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("action param blk in mmkubernetes:\n"); + cnfparamsPrint(&actpblk, pvals); + } + + CODE_STD_STRING_REQUESTnewActInst(1) + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); + CHKiRet(createInstance(&pData)); + + pData->de_dot = loadModConf->de_dot; + pData->allowUnsignedCerts = loadModConf->allowUnsignedCerts; + pData->skipVerifyHost = loadModConf->skipVerifyHost; + pData->busyRetryInterval = loadModConf->busyRetryInterval; + pData->sslPartialChain = loadModConf->sslPartialChain; + pData->cacheEntryTTL = loadModConf->cacheEntryTTL; + pData->cacheExpireInterval = loadModConf->cacheExpireInterval; + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) { + continue; + } else if(!strcmp(actpblk.descr[i].name, "kubernetesurl")) { + free(pData->kubernetesUrl); + pData->kubernetesUrl = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "srcmetadatapath")) { + msgPropDescrDestruct(pData->srcMetadataDescr); + free(pData->srcMetadataDescr); + CHKmalloc(pData->srcMetadataDescr = malloc(sizeof(msgPropDescr_t))); + srcMetadataPath = es_str2cstr(pvals[i].val.d.estr, NULL); + CHKiRet(msgPropDescrFill(pData->srcMetadataDescr, (uchar *)srcMetadataPath, + strlen(srcMetadataPath))); + /* todo: sanitize the path */ + } else if(!strcmp(actpblk.descr[i].name, "dstmetadatapath")) { + free(pData->dstMetadataPath); + pData->dstMetadataPath = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + /* todo: sanitize the path */ + } else if(!strcmp(actpblk.descr[i].name, "tls.cacert")) { + free(pData->caCertFile); + pData->caCertFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->caCertFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: certificate file %s couldn't be accessed: %s\n", + pData->caCertFile, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(actpblk.descr[i].name, "tls.mycert")) { + pData->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->myCertFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: 'tls.mycert' file %s couldn't be accessed: %s\n", + pData->myCertFile, errStr); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(actpblk.descr[i].name, "tls.myprivkey")) { + pData->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->myPrivKeyFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n", + pData->myPrivKeyFile, errStr); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(actpblk.descr[i].name, "allowunsignedcerts")) { + pData->allowUnsignedCerts = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "skipverifyhost")) { + pData->skipVerifyHost = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "token")) { + free(pData->token); + pData->token = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "tokenfile")) { + free(pData->tokenFile); + pData->tokenFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->tokenFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: token file %s couldn't be accessed: %s\n", + pData->tokenFile, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(actpblk.descr[i].name, "annotation_match")) { + free_annotationmatch(&pData->annotation_match); + if (RS_RET_OK != (iRet = init_annotationmatch(&pData->annotation_match, pvals[i].val.d.ar))) + ABORT_FINALIZE(iRet); + } else if(!strcmp(actpblk.descr[i].name, "de_dot")) { + pData->de_dot = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "de_dot_separator")) { + free(pData->de_dot_separator); + pData->de_dot_separator = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); +#if HAVE_LOADSAMPLESFROMSTRING == 1 + } else if(!strcmp(modpblk.descr[i].name, "filenamerules")) { + free(pData->fnRules); + CHKiRet((array_to_rules(pvals[i].val.d.ar, &pData->fnRules))); +#endif + } else if(!strcmp(modpblk.descr[i].name, "filenamerulebase")) { + free(pData->fnRulebase); + pData->fnRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->fnRulebase, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: filenamerulebase file %s couldn't be accessed: %s\n", + pData->fnRulebase, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } +#if HAVE_LOADSAMPLESFROMSTRING == 1 + } else if(!strcmp(modpblk.descr[i].name, "containerrules")) { + free(pData->contRules); + CHKiRet((array_to_rules(pvals[i].val.d.ar, &pData->contRules))); +#endif + } else if(!strcmp(modpblk.descr[i].name, "containerrulebase")) { + free(pData->contRulebase); + pData->contRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->contRulebase, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + iRet = RS_RET_NO_FILE_ACCESS; + LogError(0, iRet, + "error: containerrulebase file %s couldn't be accessed: %s\n", + pData->contRulebase, errStr); + ABORT_FINALIZE(iRet); + } else { + fclose(fp); + fp = NULL; + } + } else if(!strcmp(actpblk.descr[i].name, "busyretryinterval")) { + pData->busyRetryInterval = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "sslpartialchain")) { +#if defined(SUPPORT_SSL_PARTIAL_CHAIN) + pData->sslPartialChain = pvals[i].val.d.n; +#else + LogMsg(0, RS_RET_VALUE_NOT_IN_THIS_MODE, LOG_INFO, + "sslpartialchain is only supported for OpenSSL\n"); +#endif + } else if(!strcmp(actpblk.descr[i].name, "cacheentryttl")) { + pData->cacheEntryTTL = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "cacheexpireinterval")) { + pData->cacheExpireInterval = pvals[i].val.d.n; + } else { + dbgprintf("mmkubernetes: program error, non-handled " + "param '%s' in action() block\n", actpblk.descr[i].name); + /* todo: error message? */ + } + } + +#if HAVE_LOADSAMPLESFROMSTRING == 1 + if (pData->fnRules && pData->fnRulebase) { + LogError(0, RS_RET_CONFIG_ERROR, + "mmkubernetes: only 1 of filenamerules or filenamerulebase may be used"); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + if (pData->contRules && pData->contRulebase) { + LogError(0, RS_RET_CONFIG_ERROR, + "mmkubernetes: only 1 of containerrules or containerrulebase may be used"); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } +#endif + CHKiRet(set_lnctx(&pData->fnCtxln, pData->fnRules, pData->fnRulebase, + loadModConf->fnRules, loadModConf->fnRulebase)); + CHKiRet(set_lnctx(&pData->contCtxln, pData->contRules, pData->contRulebase, + loadModConf->contRules, loadModConf->contRulebase)); + + if ((pData->cacheExpireInterval > -1)) { + if ((pData->cacheEntryTTL < 0)) { + LogError(0, RS_RET_CONFIG_ERROR, + "mmkubernetes: cacheentryttl value [%d] is invalid - " + "value must be 0 or greater", + pData->cacheEntryTTL); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + } + + if(pData->kubernetesUrl == NULL) { + if(loadModConf->kubernetesUrl == NULL) { + CHKmalloc(pData->kubernetesUrl = (uchar *) strdup(DFLT_KUBERNETES_URL)); + } else { + CHKmalloc(pData->kubernetesUrl = (uchar *) strdup((char *) loadModConf->kubernetesUrl)); + } + } + if(pData->srcMetadataDescr == NULL) { + CHKmalloc(pData->srcMetadataDescr = malloc(sizeof(msgPropDescr_t))); + CHKiRet(msgPropDescrFill(pData->srcMetadataDescr, loadModConf->srcMetadataPath, + strlen((char *)loadModConf->srcMetadataPath))); + } + if(pData->dstMetadataPath == NULL) + pData->dstMetadataPath = (uchar *) strdup((char *) loadModConf->dstMetadataPath); + if(pData->caCertFile == NULL && loadModConf->caCertFile) + pData->caCertFile = (uchar *) strdup((char *) loadModConf->caCertFile); + if(pData->myCertFile == NULL && loadModConf->myCertFile) + pData->myCertFile = (uchar *) strdup((char *) loadModConf->myCertFile); + if(pData->myPrivKeyFile == NULL && loadModConf->myPrivKeyFile) + pData->myPrivKeyFile = (uchar *) strdup((char *) loadModConf->myPrivKeyFile); + if(pData->token == NULL && loadModConf->token) + pData->token = (uchar *) strdup((char *) loadModConf->token); + if(pData->tokenFile == NULL && loadModConf->tokenFile) + pData->tokenFile = (uchar *) strdup((char *) loadModConf->tokenFile); + if(pData->de_dot_separator == NULL && loadModConf->de_dot_separator) + pData->de_dot_separator = (uchar *) strdup((char *) loadModConf->de_dot_separator); + if((pData->annotation_match.nmemb == 0) && (loadModConf->annotation_match.nmemb > 0)) + copy_annotationmatch(&loadModConf->annotation_match, &pData->annotation_match); + + if(pData->de_dot_separator) + pData->de_dot_separator_len = strlen((const char *)pData->de_dot_separator); + + CHKmalloc(pData->contNameDescr = malloc(sizeof(msgPropDescr_t))); + CHKiRet(msgPropDescrFill(pData->contNameDescr, (uchar*) DFLT_CONTAINER_NAME, + strlen(DFLT_CONTAINER_NAME))); + CHKmalloc(pData->contIdFullDescr = malloc(sizeof(msgPropDescr_t))); + CHKiRet(msgPropDescrFill(pData->contIdFullDescr, (uchar*) DFLT_CONTAINER_ID_FULL, + strlen(DFLT_CONTAINER_NAME))); + + /* get the cache for this url */ + for(i = 0; caches[i] != NULL; i++) { + if(!strcmp((char *) pData->kubernetesUrl, (char *) caches[i]->kbUrl)) + break; + } + if(caches[i] != NULL) { + pData->cache = caches[i]; + } else { + CHKmalloc(pData->cache = cacheNew(pData)); + struct cache_s **new_caches = realloc(caches, (i + 2) * sizeof(struct cache_s *)); + CHKmalloc(new_caches); + caches = new_caches; + caches[i] = pData->cache; + caches[i + 1] = NULL; + } +CODE_STD_FINALIZERnewActInst + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &actpblk); + if(fp) + fclose(fp); + free(rxstr); + free(srcMetadataPath); +ENDnewActInst + + +/* legacy config format is not supported */ +BEGINparseSelectorAct +CODESTARTparseSelectorAct +CODE_STD_STRING_REQUESTparseSelectorAct(1) + if(strncmp((char *) p, ":mmkubernetes:", sizeof(":mmkubernetes:") - 1)) { + LogError(0, RS_RET_LEGA_ACT_NOT_SUPPORTED, + "mmkubernetes supports only v6+ config format, use: " + "action(type=\"mmkubernetes\" ...)"); + } + ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); +CODE_STD_FINALIZERparseSelectorAct +ENDparseSelectorAct + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf + int i; + + free(pModConf->kubernetesUrl); + free(pModConf->srcMetadataPath); + free(pModConf->dstMetadataPath); + free(pModConf->caCertFile); + free(pModConf->myCertFile); + free(pModConf->myPrivKeyFile); + free(pModConf->token); + free(pModConf->tokenFile); + free(pModConf->de_dot_separator); + free(pModConf->fnRules); + free(pModConf->fnRulebase); + free(pModConf->contRules); + free(pModConf->contRulebase); + free_annotationmatch(&pModConf->annotation_match); + for(i = 0; caches[i] != NULL; i++) { + dbgprintf("mmkubernetes: freeing cache [%d] mdht [%p] nsht [%p]\n", + i, caches[i]->mdHt, caches[i]->nsHt); + cacheFree(caches[i]); + } + free(caches); +ENDfreeCnf + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + dbgprintf("mmkubernetes\n"); + dbgprintf("\tkubernetesUrl='%s'\n", pData->kubernetesUrl); + dbgprintf("\tsrcMetadataPath='%s'\n", pData->srcMetadataDescr->name); + dbgprintf("\tdstMetadataPath='%s'\n", pData->dstMetadataPath); + dbgprintf("\ttls.cacert='%s'\n", pData->caCertFile); + dbgprintf("\ttls.mycert='%s'\n", pData->myCertFile); + dbgprintf("\ttls.myprivkey='%s'\n", pData->myPrivKeyFile); + dbgprintf("\tallowUnsignedCerts='%d'\n", pData->allowUnsignedCerts); + dbgprintf("\tskipVerifyHost='%d'\n", pData->skipVerifyHost); + dbgprintf("\ttoken='%s'\n", pData->token); + dbgprintf("\ttokenFile='%s'\n", pData->tokenFile); + dbgprintf("\tde_dot='%d'\n", pData->de_dot); + dbgprintf("\tde_dot_separator='%s'\n", pData->de_dot_separator); + dbgprintf("\tfilenamerulebase='%s'\n", pData->fnRulebase); + dbgprintf("\tcontainerrulebase='%s'\n", pData->contRulebase); +#if HAVE_LOADSAMPLESFROMSTRING == 1 + dbgprintf("\tfilenamerules='%s'\n", pData->fnRules); + dbgprintf("\tcontainerrules='%s'\n", pData->contRules); +#endif + dbgprintf("\tbusyretryinterval='%d'\n", pData->busyRetryInterval); + dbgprintf("\tcacheentryttl='%d'\n", pData->cacheEntryTTL); + dbgprintf("\tcacheexpireinterval='%d'\n", pData->cacheExpireInterval); +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +static rsRetVal +extractMsgMetadata(smsg_t *pMsg, instanceData *pData, struct json_object **json) +{ + DEFiRet; + uchar *filename = NULL, *container_name = NULL, *container_id_full = NULL; + rs_size_t fnLen, container_name_len, container_id_full_len; + unsigned short freeFn = 0, free_container_name = 0, free_container_id_full = 0; + int lnret; + struct json_object *cnid = NULL; + + if (!json) + FINALIZE; + *json = NULL; + /* extract metadata from the CONTAINER_NAME field and see if CONTAINER_ID_FULL is present */ + container_name = MsgGetProp(pMsg, NULL, pData->contNameDescr, + &container_name_len, &free_container_name, NULL); + container_id_full = MsgGetProp( + pMsg, NULL, pData->contIdFullDescr, &container_id_full_len, &free_container_id_full, NULL); + + if (container_name && container_id_full && container_name_len && container_id_full_len) { + dbgprintf("mmkubernetes: CONTAINER_NAME: '%s' CONTAINER_ID_FULL: '%s'.\n", + container_name, container_id_full); + if ((lnret = ln_normalize(pData->contCtxln, (char*)container_name, + container_name_len, json))) { + if (LN_WRONGPARSER != lnret) { + LogMsg(0, RS_RET_ERR, LOG_ERR, + "mmkubernetes: error parsing container_name [%s]: [%d]", + container_name, lnret); + + ABORT_FINALIZE(RS_RET_ERR); + } + /* else assume parser didn't find a match and fall through */ + } else if (fjson_object_object_get_ex(*json, "pod_name", NULL) && + fjson_object_object_get_ex(*json, "namespace_name", NULL) && + fjson_object_object_get_ex(*json, "container_name", NULL)) { + /* if we have fields for pod name, namespace name, container name, + * and container id, we are good to go */ + /* add field for container id */ + json_object_object_add(*json, "container_id", + json_object_new_string_len((const char *)container_id_full, + container_id_full_len)); + ABORT_FINALIZE(RS_RET_OK); + } + } + + /* extract metadata from the file name */ + filename = MsgGetProp(pMsg, NULL, pData->srcMetadataDescr, &fnLen, &freeFn, NULL); + if((filename == NULL) || (fnLen == 0)) + ABORT_FINALIZE(RS_RET_NOT_FOUND); + + dbgprintf("mmkubernetes: filename: '%s' len %d.\n", filename, fnLen); + if ((lnret = ln_normalize(pData->fnCtxln, (char*)filename, fnLen, json))) { + if (LN_WRONGPARSER != lnret) { + LogMsg(0, RS_RET_ERR, LOG_ERR, + "mmkubernetes: error parsing container_name [%s]: [%d]", + filename, lnret); + + ABORT_FINALIZE(RS_RET_ERR); + } else { + /* no match */ + ABORT_FINALIZE(RS_RET_NOT_FOUND); + } + } + /* if we have fields for pod name, namespace name, container name, + * and container id, we are good to go */ + if (fjson_object_object_get_ex(*json, "pod_name", NULL) && + fjson_object_object_get_ex(*json, "namespace_name", NULL) && + fjson_object_object_get_ex(*json, "container_name_and_id", &cnid)) { + /* parse container_name_and_id into container_name and container_id */ + const char *container_name_and_id = json_object_get_string(cnid); + const char *last_dash = NULL; + if (container_name_and_id && (last_dash = strrchr(container_name_and_id, '-')) && + *(last_dash + 1) && (last_dash != container_name_and_id)) { + json_object_object_add(*json, "container_name", + json_object_new_string_len(container_name_and_id, + (int)(last_dash-container_name_and_id))); + json_object_object_add(*json, "container_id", + json_object_new_string(last_dash + 1)); + ABORT_FINALIZE(RS_RET_OK); + } + } + ABORT_FINALIZE(RS_RET_NOT_FOUND); +finalize_it: + if(freeFn) + free(filename); + if (free_container_name) + free(container_name); + if (free_container_id_full) + free(container_id_full); + if (iRet != RS_RET_OK) { + json_object_put(*json); + *json = NULL; + } + RETiRet; +} + + +static rsRetVal +queryKB(wrkrInstanceData_t *pWrkrData, char *url, time_t now, struct json_object **rply) +{ + DEFiRet; + CURLcode ccode; + struct json_tokener *jt = NULL; + struct json_object *jo; + long resp_code = 400; + + if (pWrkrData->pData->cache->lastBusyTime) { + now -= pWrkrData->pData->cache->lastBusyTime; + if (now < pWrkrData->pData->busyRetryInterval) { + LogMsg(0, RS_RET_RETRY, LOG_DEBUG, + "mmkubernetes: Waited [%ld] of [%d] seconds for the requested url [%s]\n", + now, pWrkrData->pData->busyRetryInterval, url); + ABORT_FINALIZE(RS_RET_RETRY); + } else { + LogMsg(0, RS_RET_OK, LOG_DEBUG, + "mmkubernetes: Cleared busy status after [%d] seconds - " + "will retry the requested url [%s]\n", + pWrkrData->pData->busyRetryInterval, url); + pWrkrData->pData->cache->lastBusyTime = 0; + } + } + + /* query kubernetes for pod info */ + ccode = curl_easy_setopt(pWrkrData->curlCtx, CURLOPT_URL, url); + if(ccode != CURLE_OK) + ABORT_FINALIZE(RS_RET_ERR); + if(CURLE_OK != (ccode = curl_easy_perform(pWrkrData->curlCtx))) { + LogMsg(0, RS_RET_ERR, LOG_ERR, + "mmkubernetes: failed to connect to [%s] - %d:%s\n", + url, ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + if(CURLE_OK != (ccode = curl_easy_getinfo(pWrkrData->curlCtx, + CURLINFO_RESPONSE_CODE, &resp_code))) { + LogMsg(0, RS_RET_ERR, LOG_ERR, + "mmkubernetes: could not get response code from query to [%s] - %d:%s\n", + url, ccode, curl_easy_strerror(ccode)); + ABORT_FINALIZE(RS_RET_ERR); + } + if(resp_code == 401) { + LogMsg(0, RS_RET_ERR, LOG_ERR, + "mmkubernetes: Unauthorized: not allowed to view url - " + "check token/auth credentials [%s]\n", + url); + ABORT_FINALIZE(RS_RET_ERR); + } + if(resp_code == 403) { + LogMsg(0, RS_RET_ERR, LOG_ERR, + "mmkubernetes: Forbidden: no access - " + "check permissions to view url [%s]\n", + url); + ABORT_FINALIZE(RS_RET_ERR); + } + if(resp_code == 404) { + LogMsg(0, RS_RET_NOT_FOUND, LOG_INFO, + "mmkubernetes: Not Found: the resource does not exist at url [%s]\n", + url); + ABORT_FINALIZE(RS_RET_NOT_FOUND); + } + if(resp_code == 429) { + if (pWrkrData->pData->busyRetryInterval) { + pWrkrData->pData->cache->lastBusyTime = now; + } + + LogMsg(0, RS_RET_RETRY, LOG_INFO, + "mmkubernetes: Too Many Requests: the server is too heavily loaded " + "to provide the data for the requested url [%s]\n", + url); + ABORT_FINALIZE(RS_RET_RETRY); + } + if(resp_code != 200) { + LogMsg(0, RS_RET_ERR, LOG_ERR, + "mmkubernetes: server returned unexpected code [%ld] for url [%s]\n", + resp_code, url); + ABORT_FINALIZE(RS_RET_ERR); + } + /* parse retrieved data */ + jt = json_tokener_new(); + json_tokener_reset(jt); + jo = json_tokener_parse_ex(jt, pWrkrData->curlRply, pWrkrData->curlRplyLen); + json_tokener_free(jt); + if(!json_object_is_type(jo, json_type_object)) { + json_object_put(jo); + jo = NULL; + LogMsg(0, RS_RET_JSON_PARSE_ERR, LOG_INFO, + "mmkubernetes: unable to parse string as JSON:[%.*s]\n", + (int)pWrkrData->curlRplyLen, pWrkrData->curlRply); + ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR); + } + + dbgprintf("mmkubernetes: queryKB reply:\n%s\n", + json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY)); + + *rply = jo; + +finalize_it: + if(pWrkrData->curlRply != NULL) { + free(pWrkrData->curlRply); + pWrkrData->curlRply = NULL; + pWrkrData->curlRplyLen = 0; + } + RETiRet; +} + + +/* versions < 8.16.0 don't support BEGINdoAction_NoStrings */ +#if defined(BEGINdoAction_NoStrings) +BEGINdoAction_NoStrings + smsg_t **ppMsg = (smsg_t **) pMsgData; + smsg_t *pMsg = ppMsg[0]; +#else +BEGINdoAction + smsg_t *pMsg = (smsg_t*) ppString[0]; +#endif + const char *podName = NULL, *ns = NULL, *containerName = NULL, + *containerID = NULL; + char *mdKey = NULL; + struct json_object *jMetadata = NULL, *jMetadataCopy = NULL, *jMsgMeta = NULL, + *jo = NULL; + int add_pod_metadata = 1; + time_t now; + +CODESTARTdoAction + CHKiRet_Hdlr(extractMsgMetadata(pMsg, pWrkrData->pData, &jMsgMeta)) { + ABORT_FINALIZE((iRet == RS_RET_NOT_FOUND) ? RS_RET_OK : iRet); + } + + datetime.GetTime(&now); + STATSCOUNTER_INC(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen); + + if (fjson_object_object_get_ex(jMsgMeta, "pod_name", &jo)) + podName = json_object_get_string(jo); + if (fjson_object_object_get_ex(jMsgMeta, "namespace_name", &jo)) + ns = json_object_get_string(jo); + if (fjson_object_object_get_ex(jMsgMeta, "container_name", &jo)) + containerName = json_object_get_string(jo); + if (fjson_object_object_get_ex(jMsgMeta, "container_id", &jo)) + containerID = json_object_get_string(jo); + assert(podName != NULL); + assert(ns != NULL); + assert(containerName != NULL); + assert(containerID != NULL); + + dbgprintf("mmkubernetes:\n podName: '%s'\n namespace: '%s'\n containerName: '%s'\n" + " containerID: '%s'\n", podName, ns, containerName, containerID); + + /* check cache for metadata */ + if ((-1 == asprintf(&mdKey, "%s_%s_%s", ns, podName, containerName)) || + (!mdKey)) { + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + pthread_mutex_lock(pWrkrData->pData->cache->cacheMtx); + jMetadata = cache_entry_get_md(pWrkrData, mdKey, now); + + if(jMetadata == NULL) { + char *url = NULL; + struct json_object *jReply = NULL, *jo2 = NULL, *jNsMeta = NULL, *jPodData = NULL; + + /* check cache for namespace metadata */ + jNsMeta = cache_entry_get_nsmd(pWrkrData, (const char *)ns, now); + + if(jNsMeta == NULL) { + /* query kubernetes for namespace info */ + /* todo: move url definitions elsewhere */ + if ((-1 == asprintf(&url, "%s/api/v1/namespaces/%s", + (char *) pWrkrData->pData->kubernetesUrl, ns)) || + (!url)) { + pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + iRet = queryKB(pWrkrData, url, now, &jReply); + free(url); + if (iRet == RS_RET_NOT_FOUND) { + /* negative cache namespace - make a dummy empty namespace metadata object */ + jNsMeta = json_object_new_object(); + STATSCOUNTER_INC(pWrkrData->namespaceMetadataNotFound, + pWrkrData->mutNamespaceMetadataNotFound); + } else if (iRet == RS_RET_RETRY) { + /* server is busy - retry or error */ + STATSCOUNTER_INC(pWrkrData->namespaceMetadataBusy, + pWrkrData->mutNamespaceMetadataBusy); + if (0 == pWrkrData->pData->busyRetryInterval) { + pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); + ABORT_FINALIZE(RS_RET_ERR); + } + add_pod_metadata = 0; /* don't cache pod metadata either - retry both */ + } else if (iRet != RS_RET_OK) { + /* one of many possible transient errors: apiserver error, network, config, auth. + * Instead of causing hard error and disabling this module, we can return + * basic namespace metadata that is extracted from container log file path. + * When transient error resolves, other metadata will become + * available. For a new a new pod whose metadata is not yet cached, this + * will allow 401, 403, 500, etc. return status from apiserver treated + * similar to 404 returns. + * */ + jNsMeta = json_object_new_object(); + STATSCOUNTER_INC(pWrkrData->namespaceMetadataError, + pWrkrData->mutNamespaceMetadataError); + } else if (fjson_object_object_get_ex(jReply, "metadata", &jNsMeta)) { + jNsMeta = json_object_get(jNsMeta); + parse_labels_annotations(jNsMeta, &pWrkrData->pData->annotation_match, + pWrkrData->pData->de_dot, + (const char *)pWrkrData->pData->de_dot_separator, + pWrkrData->pData->de_dot_separator_len); + STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess, + pWrkrData->mutNamespaceMetadataSuccess); + } else { + /* namespace with no metadata??? */ + LogMsg(0, RS_RET_ERR, LOG_INFO, + "mmkubernetes: namespace [%s] has no metadata!\n", ns); + /* negative cache namespace - make a dummy empty namespace metadata object */ + jNsMeta = json_object_new_object(); + STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess, + pWrkrData->mutNamespaceMetadataSuccess); + } + + if(jNsMeta) { + if ((iRet = cache_entry_add_nsmd(pWrkrData, ns, jNsMeta, now))) { + ABORT_FINALIZE(iRet); + } + } + json_object_put(jReply); + jReply = NULL; + } + + if ((-1 == asprintf(&url, "%s/api/v1/namespaces/%s/pods/%s", + (char *) pWrkrData->pData->kubernetesUrl, ns, podName)) || + (!url)) { + pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + iRet = queryKB(pWrkrData, url, now, &jReply); + free(url); + if (iRet == RS_RET_NOT_FOUND) { + /* negative cache pod - make a dummy empty pod metadata object */ + iRet = RS_RET_OK; + STATSCOUNTER_INC(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound); + } else if (iRet == RS_RET_RETRY) { + /* server is busy - retry or error */ + STATSCOUNTER_INC(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy); + if (0 == pWrkrData->pData->busyRetryInterval) { + pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); + ABORT_FINALIZE(RS_RET_ERR); + } + add_pod_metadata = 0; /* do not cache so that we can retry */ + iRet = RS_RET_OK; + } else if(iRet != RS_RET_OK) { + /* This is likely caused by transient apiserver errors: 401, 403, 500, etc. + * Treat it similar to 404 while returning file path based pod metadata. + * When transient error condition resolves, additional metadata will be + * available for events originating from a new pod whose metatadata is not + * yet cached. + * */ + iRet = RS_RET_OK; + STATSCOUNTER_INC(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError); + } else { + STATSCOUNTER_INC(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess); + } + + jo = json_object_new_object(); + if(jNsMeta && fjson_object_object_get_ex(jNsMeta, "uid", &jo2)) + json_object_object_add(jo, "namespace_id", json_object_get(jo2)); + if(jNsMeta && fjson_object_object_get_ex(jNsMeta, "labels", &jo2)) + json_object_object_add(jo, "namespace_labels", json_object_get(jo2)); + if(jNsMeta && fjson_object_object_get_ex(jNsMeta, "annotations", &jo2)) + json_object_object_add(jo, "namespace_annotations", json_object_get(jo2)); + if(jNsMeta && fjson_object_object_get_ex(jNsMeta, "creationTimestamp", &jo2)) + json_object_object_add(jo, "creation_timestamp", json_object_get(jo2)); + if(fjson_object_object_get_ex(jReply, "metadata", &jPodData)) { + if(fjson_object_object_get_ex(jPodData, "uid", &jo2)) + json_object_object_add(jo, "pod_id", json_object_get(jo2)); + parse_labels_annotations(jPodData, &pWrkrData->pData->annotation_match, + pWrkrData->pData->de_dot, + (const char *)pWrkrData->pData->de_dot_separator, + pWrkrData->pData->de_dot_separator_len); + if(fjson_object_object_get_ex(jPodData, "annotations", &jo2)) + json_object_object_add(jo, "annotations", json_object_get(jo2)); + if(fjson_object_object_get_ex(jPodData, "labels", &jo2)) + json_object_object_add(jo, "labels", json_object_get(jo2)); + } + if(fjson_object_object_get_ex(jReply, "spec", &jPodData)) { + if(fjson_object_object_get_ex(jPodData, "nodeName", &jo2)) { + json_object_object_add(jo, "host", json_object_get(jo2)); + } + } + json_object_put(jReply); + jReply = NULL; + + if (fjson_object_object_get_ex(jMsgMeta, "pod_name", &jo2)) + json_object_object_add(jo, "pod_name", json_object_get(jo2)); + if (fjson_object_object_get_ex(jMsgMeta, "namespace_name", &jo2)) + json_object_object_add(jo, "namespace_name", json_object_get(jo2)); + if (fjson_object_object_get_ex(jMsgMeta, "container_name", &jo2)) + json_object_object_add(jo, "container_name", json_object_get(jo2)); + json_object_object_add(jo, "master_url", + json_object_new_string((const char *)pWrkrData->pData->kubernetesUrl)); + jMetadata = json_object_new_object(); + json_object_object_add(jMetadata, "kubernetes", jo); + jo = json_object_new_object(); + if (fjson_object_object_get_ex(jMsgMeta, "container_id", &jo2)) + json_object_object_add(jo, "container_id", json_object_get(jo2)); + json_object_object_add(jMetadata, "docker", jo); + + if (add_pod_metadata) { + if ((iRet = cache_entry_add_md(pWrkrData, mdKey, jMetadata, now))) + ABORT_FINALIZE(iRet); + mdKey = NULL; + } + } + + /* make a copy of the metadata for the msg to own */ + /* todo: use json_object_deep_copy when implementation available in libfastjson */ + /* yes, this is expensive - but there is no other way to make this thread safe - we + * can't allow the msg to have a shared pointer to an element inside the cache, + * outside of the cache lock + */ + jMetadataCopy = json_tokener_parse(json_object_get_string(jMetadata)); + if (!add_pod_metadata) { + /* jMetadata object was created from scratch and not cached */ + json_object_put(jMetadata); + jMetadata = NULL; + } + pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); + /* the +1 is there to skip the leading '$' */ + msgAddJSON(pMsg, (uchar *) pWrkrData->pData->dstMetadataPath + 1, jMetadataCopy, 0, 0); + +finalize_it: + json_object_put(jMsgMeta); + free(mdKey); +ENDdoAction + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + + +/* all the macros bellow have to be in a specific order */ +BEGINmodExit +CODESTARTmodExit + curl_global_cleanup(); + + objRelease(datetime, CORE_COMPONENT); + objRelease(regexp, LM_REGEXP_FILENAME); + objRelease(statsobj, CORE_COMPONENT); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmkubernetes: module compiled with rsyslog version %s.\n", VERSION); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); + CHKiRet(objUse(regexp, LM_REGEXP_FILENAME)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + /* CURL_GLOBAL_ALL initializes more than is needed but the + * libcurl documentation discourages use of other values + */ + curl_global_init(CURL_GLOBAL_ALL); +ENDmodInit diff --git a/contrib/mmrfc5424addhmac/Makefile.am b/contrib/mmrfc5424addhmac/Makefile.am new file mode 100644 index 0000000..6567def --- /dev/null +++ b/contrib/mmrfc5424addhmac/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmrfc5424addhmac.la + +mmrfc5424addhmac_la_SOURCES = mmrfc5424addhmac.c +mmrfc5424addhmac_la_CPPFLAGS = $(OPENSSL_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmrfc5424addhmac_la_LDFLAGS = -module -avoid-version +mmrfc5424addhmac_la_LIBADD = $(OPENSSL_LIBS) + +EXTRA_DIST = diff --git a/contrib/mmrfc5424addhmac/Makefile.in b/contrib/mmrfc5424addhmac/Makefile.in new file mode 100644 index 0000000..b49dff5 --- /dev/null +++ b/contrib/mmrfc5424addhmac/Makefile.in @@ -0,0 +1,801 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/mmrfc5424addhmac +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +mmrfc5424addhmac_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_mmrfc5424addhmac_la_OBJECTS = \ + mmrfc5424addhmac_la-mmrfc5424addhmac.lo +mmrfc5424addhmac_la_OBJECTS = $(am_mmrfc5424addhmac_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mmrfc5424addhmac_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(mmrfc5424addhmac_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(mmrfc5424addhmac_la_SOURCES) +DIST_SOURCES = $(mmrfc5424addhmac_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = mmrfc5424addhmac.la +mmrfc5424addhmac_la_SOURCES = mmrfc5424addhmac.c +mmrfc5424addhmac_la_CPPFLAGS = $(OPENSSL_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmrfc5424addhmac_la_LDFLAGS = -module -avoid-version +mmrfc5424addhmac_la_LIBADD = $(OPENSSL_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmrfc5424addhmac/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/mmrfc5424addhmac/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mmrfc5424addhmac.la: $(mmrfc5424addhmac_la_OBJECTS) $(mmrfc5424addhmac_la_DEPENDENCIES) $(EXTRA_mmrfc5424addhmac_la_DEPENDENCIES) + $(AM_V_CCLD)$(mmrfc5424addhmac_la_LINK) -rpath $(pkglibdir) $(mmrfc5424addhmac_la_OBJECTS) $(mmrfc5424addhmac_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mmrfc5424addhmac_la-mmrfc5424addhmac.lo: mmrfc5424addhmac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmrfc5424addhmac_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmrfc5424addhmac_la-mmrfc5424addhmac.lo -MD -MP -MF $(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Tpo -c -o mmrfc5424addhmac_la-mmrfc5424addhmac.lo `test -f 'mmrfc5424addhmac.c' || echo '$(srcdir)/'`mmrfc5424addhmac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Tpo $(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmrfc5424addhmac.c' object='mmrfc5424addhmac_la-mmrfc5424addhmac.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmrfc5424addhmac_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmrfc5424addhmac_la-mmrfc5424addhmac.lo `test -f 'mmrfc5424addhmac.c' || echo '$(srcdir)/'`mmrfc5424addhmac.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/mmrfc5424addhmac/mmrfc5424addhmac.c b/contrib/mmrfc5424addhmac/mmrfc5424addhmac.c new file mode 100644 index 0000000..b696ca1 --- /dev/null +++ b/contrib/mmrfc5424addhmac/mmrfc5424addhmac.c @@ -0,0 +1,382 @@ +/* mmrfc5424addhmac.c + * custom module: add hmac to RFC5424 messages + * + * Note on important design decision: This module is fully self-contained. + * Most importantly, it does not rely on mmpstrucdata to populate the + * structured data portion of the messages JSON. There are two reasons + * for this: + * 1. robustness + * - this guard against misconfiguration + * - it permits us to be more liberal in regard to malformed + * structured data + * - it permits us to handle border-cases (like duplicate + * SD-IDs) with much less complexity + * 2. performance + * With being "on the spot" of what we need we can reduce memory + * reads and writes. This is a considerable save if the JSON representation + * is not otherwise needed. + * + * Note that the recommended calling sequence if both of these modules + * are used is + * + * 1. mmrfc5424addhmac + * 2. mmpstrucdata + * + * This sequence permits mmpstrucdata to pick up the modifications we + * made in this module here. + * + * Copyright 2013 Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <stdint.h> +#include <openssl/hmac.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("mmrfc5424addhmac") + + +DEF_OMOD_STATIC_DATA + +/* config variables */ + +typedef struct _instanceData { + uchar *key; + int16_t keylen; /* cached length of key, to avoid recomputation */ + uchar *sdid; /* SD-ID to be used to persist the hmac */ + int16_t sdidLen; + const EVP_MD *algo; +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; +} wrkrInstanceData_t; + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ +}; +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current exec process */ + + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "key", eCmdHdlrString, 1 }, + { "hashfunction", eCmdHdlrString, 1 }, + { "sd_id", eCmdHdlrGetWord, 1 } +}; +static struct cnfparamblk actpblk = + { CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr + }; + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + + +BEGINfreeInstance +CODESTARTfreeInstance +ENDfreeInstance + + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + + +static inline void +setInstParamDefaults(instanceData *pData) +{ + pData->key = NULL; +} + +BEGINnewActInst + struct cnfparamvals *pvals; + char *ciphername; + int i; +CODESTARTnewActInst + DBGPRINTF("newActInst (mmrfc5424addhmac)\n"); + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CODE_STD_STRING_REQUESTnewActInst(1) + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(actpblk.descr[i].name, "key")) { + pData->key = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + pData->keylen = es_strlen(pvals[i].val.d.estr); + } else if(!strcmp(actpblk.descr[i].name, "hashfunction")) { + ciphername = es_str2cstr(pvals[i].val.d.estr, NULL); + pData->algo = EVP_get_digestbyname(ciphername); + if(pData->algo == NULL) { + LogError(0, RS_RET_CRY_INVLD_ALGO, + "hashFunction '%s' unknown to openssl - " + "cannot continue", ciphername); + free(ciphername); + ABORT_FINALIZE(RS_RET_CRY_INVLD_ALGO); + } + free(ciphername); + } else if(!strcmp(actpblk.descr[i].name, "sd_id")) { + pData->sdid = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + pData->sdidLen = es_strlen(pvals[i].val.d.estr); + } else { + dbgprintf("mmrfc5424addhmac: program error, non-handled " + "param '%s'\n", actpblk.descr[i].name); + } + } + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + + +/* turn the binary data in bin of length len into a + * printable hex string. "print" must be 2*len+1 (for \0) + */ +static void +hexify(uchar *bin, int len, uchar *print) +{ + static const char hexchars[16] = + {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + int iSrc, iDst; + + for(iSrc = iDst = 0 ; iSrc < len ; ++iSrc) { + print[iDst++] = hexchars[bin[iSrc]>>4]; + print[iDst++] = hexchars[bin[iSrc]&0x0f]; + } + print[iDst] = '\0'; +} + + +/* skip to end of current SD-ID. This function can be improved + * in regard to fully parsing based on RFC5424, HOWEVER, this would + * also reduce performance. So we consider the current implementation + * to be superior. + */ +static void +skipSDID(uchar *sdbuf, int sdlen, int *rootIdx) +{ + int i; + i = *rootIdx; + while(i < sdlen) { + if(sdbuf[i] == ']') { + if(i > *rootIdx && sdbuf[i-1] == '\\') { + ; /* escaped, nothing to do! */ + } else { + ++i; /* eat ']' */ + break; + } + } + ++i; + } + *rootIdx = i; +} + +static void +getSDID(uchar *sdbuf, int sdlen, int *rootIdx, uchar *sdid) +{ + int i, j; + i = *rootIdx; + j = 0; + + if(sdbuf[i] != '[') { + ++i; + goto done; + } + + ++i; + while(i < sdlen && sdbuf[i] != '=' && sdbuf[i] != ' ' + && sdbuf[i] != ']' && sdbuf[i] != '"') { + sdid[j++] = sdbuf[i++]; + } +done: + sdid[j] = '\0'; + *rootIdx = i; +} + +/* check if "our" hmac is already present */ +static sbool +isHmacPresent(instanceData *pData, smsg_t *pMsg) +{ + uchar *sdbuf; + rs_size_t sdlen; + sbool found; + int i; + uchar sdid[33]; /* RFC-based size limit */ + + MsgGetStructuredData(pMsg, &sdbuf, &sdlen); + found = 0; + + if(sdbuf[0] == '-') /* RFC: struc data is empty! */ + goto done; + + i = 0; + while(i < sdlen && !found) { + getSDID(sdbuf, sdlen, &i, sdid); + if(!strcmp((char*)pData->sdid, (char*)sdid)) { + found = 1; + break; + } + skipSDID(sdbuf, sdlen, &i); + } + +done: + return found; +} + +static rsRetVal +hashMsg(instanceData *pData, smsg_t *pMsg) +{ + uchar *pRawMsg; + int lenRawMsg; + uchar *sdbuf; + rs_size_t sdlen; + unsigned int hashlen; + uchar hash[EVP_MAX_MD_SIZE]; + uchar hashPrintable[2*EVP_MAX_MD_SIZE+1]; + uchar newsd[64*1024]; /* we assume this is sufficient... */ + int lenNewsd; + DEFiRet; + + MsgGetStructuredData(pMsg, &sdbuf, &sdlen); + getRawMsg(pMsg, &pRawMsg, &lenRawMsg); + HMAC(pData->algo, pData->key, pData->keylen, + pRawMsg, lenRawMsg, hash, &hashlen); + hexify(hash, hashlen, hashPrintable); + lenNewsd = snprintf((char*)newsd, sizeof(newsd), "[%s hash=\"%s\"]", + (char*)pData->sdid, (char*)hashPrintable); + MsgAddToStructuredData(pMsg, newsd, lenNewsd); + RETiRet; +} + + +BEGINdoAction + instanceData *pData = pWrkrData->pData; + smsg_t *pMsg; +CODESTARTdoAction + pMsg = (smsg_t*) ppString[0]; + if( msgGetProtocolVersion(pMsg) == MSG_RFC5424_PROTOCOL + && !isHmacPresent(pData, pMsg)) { + hashMsg(pData, pMsg); + } else { + if(Debug) { + uchar *pRawMsg; + int lenRawMsg; + getRawMsg(pMsg, &pRawMsg, &lenRawMsg); + dbgprintf("mmrfc5424addhmac: non-rfc5424 or HMAC already " + "present: %.256s\n", pRawMsg); + } + } +ENDdoAction + + +NO_LEGACY_CONF_parseSelectorAct + + +BEGINmodExit +CODESTARTmodExit + EVP_cleanup(); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +ENDqueryEtryPt + + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; +CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmrfc5424addhmac: module compiled with rsyslog version %s.\n", VERSION); + OpenSSL_add_all_digests(); +ENDmodInit diff --git a/contrib/mmsequence/Makefile.am b/contrib/mmsequence/Makefile.am new file mode 100644 index 0000000..543d6d8 --- /dev/null +++ b/contrib/mmsequence/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmsequence.la + +mmsequence_la_SOURCES = mmsequence.c +mmsequence_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmsequence_la_LDFLAGS = -module -avoid-version +mmsequence_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/mmsequence/Makefile.in b/contrib/mmsequence/Makefile.in new file mode 100644 index 0000000..00aadbd --- /dev/null +++ b/contrib/mmsequence/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/mmsequence +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +mmsequence_la_DEPENDENCIES = +am_mmsequence_la_OBJECTS = mmsequence_la-mmsequence.lo +mmsequence_la_OBJECTS = $(am_mmsequence_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mmsequence_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(mmsequence_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/mmsequence_la-mmsequence.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(mmsequence_la_SOURCES) +DIST_SOURCES = $(mmsequence_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = mmsequence.la +mmsequence_la_SOURCES = mmsequence.c +mmsequence_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmsequence_la_LDFLAGS = -module -avoid-version +mmsequence_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmsequence/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/mmsequence/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mmsequence.la: $(mmsequence_la_OBJECTS) $(mmsequence_la_DEPENDENCIES) $(EXTRA_mmsequence_la_DEPENDENCIES) + $(AM_V_CCLD)$(mmsequence_la_LINK) -rpath $(pkglibdir) $(mmsequence_la_OBJECTS) $(mmsequence_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmsequence_la-mmsequence.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mmsequence_la-mmsequence.lo: mmsequence.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmsequence_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmsequence_la-mmsequence.lo -MD -MP -MF $(DEPDIR)/mmsequence_la-mmsequence.Tpo -c -o mmsequence_la-mmsequence.lo `test -f 'mmsequence.c' || echo '$(srcdir)/'`mmsequence.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmsequence_la-mmsequence.Tpo $(DEPDIR)/mmsequence_la-mmsequence.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmsequence.c' object='mmsequence_la-mmsequence.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmsequence_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmsequence_la-mmsequence.lo `test -f 'mmsequence.c' || echo '$(srcdir)/'`mmsequence.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/mmsequence_la-mmsequence.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/mmsequence_la-mmsequence.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/mmsequence/mmsequence.c b/contrib/mmsequence/mmsequence.c new file mode 100644 index 0000000..78350a1 --- /dev/null +++ b/contrib/mmsequence/mmsequence.c @@ -0,0 +1,406 @@ +/* mmsequence.c + * Generate a number based on some sequence. + * + * Copyright 2013 pavel@levshin.spb.ru. + * + * Based on: mmcount.c + * Copyright 2013 Red Hat Inc. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <stdint.h> +#include <time.h> +#include <limits.h> +#include <json.h> +#include <pthread.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "hashtable.h" + +#define JSON_VAR_NAME "$!mmsequence" + +enum mmSequenceModes { + mmSequenceRandom, + mmSequencePerInstance, + mmSequencePerKey +}; + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("mmsequence") + + +DEF_OMOD_STATIC_DATA + +/* config variables */ + +typedef struct _instanceData { + enum mmSequenceModes mode; + int valueFrom; + int valueTo; + int step; + unsigned int seed; + int value; + char *pszKey; + char *pszVar; +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; +} wrkrInstanceData_t; + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ +}; +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current exec process */ + + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "mode", eCmdHdlrGetWord, 0 }, + { "from", eCmdHdlrNonNegInt, 0 }, + { "to", eCmdHdlrPositiveInt, 0 }, + { "step", eCmdHdlrNonNegInt, 0 }, + { "key", eCmdHdlrGetWord, 0 }, + { "var", eCmdHdlrGetWord, 0 }, +}; +static struct cnfparamblk actpblk = + { CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr + }; + +/* table for key-counter pairs */ +static struct hashtable *ght; +static pthread_mutex_t ght_mutex = PTHREAD_MUTEX_INITIALIZER; + +static pthread_mutex_t inst_mutex = PTHREAD_MUTEX_INITIALIZER; + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + + +BEGINfreeInstance +CODESTARTfreeInstance +ENDfreeInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + + +static inline void +setInstParamDefaults(instanceData *pData) +{ + pData->mode = mmSequencePerInstance; + pData->valueFrom = 0; + pData->valueTo = INT_MAX; + pData->step = 1; + pData->pszKey = (char*)""; + pData->pszVar = (char*)JSON_VAR_NAME; +} + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; + char *cstr; +CODESTARTnewActInst + DBGPRINTF("newActInst (mmsequence)\n"); + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CODE_STD_STRING_REQUESTnewActInst(1) + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(actpblk.descr[i].name, "mode")) { + if(!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"random", + sizeof("random")-1)) { + pData->mode = mmSequenceRandom; + } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"instance", + sizeof("instance")-1)) { + pData->mode = mmSequencePerInstance; + } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar*)"key", + sizeof("key")-1)) { + pData->mode = mmSequencePerKey; + } else { + cstr = es_str2cstr(pvals[i].val.d.estr, NULL); + LogError(0, RS_RET_INVLD_MODE, + "mmsequence: invalid mode '%s' - ignored", + cstr); + free(cstr); + } + continue; + } + if(!strcmp(actpblk.descr[i].name, "from")) { + pData->valueFrom = pvals[i].val.d.n; + continue; + } + if(!strcmp(actpblk.descr[i].name, "to")) { + pData->valueTo = pvals[i].val.d.n; + continue; + } + if(!strcmp(actpblk.descr[i].name, "step")) { + pData->step = pvals[i].val.d.n; + continue; + } + if(!strcmp(actpblk.descr[i].name, "key")) { + pData->pszKey = es_str2cstr(pvals[i].val.d.estr, NULL); + continue; + } + if(!strcmp(actpblk.descr[i].name, "var")) { + cstr = es_str2cstr(pvals[i].val.d.estr, NULL); + if (strlen(cstr) < 3) { + LogError(0, RS_RET_VALUE_NOT_SUPPORTED, + "mmsequence: valid variable name should be at least " + "3 symbols long, got %s", cstr); + free(cstr); + } else if (cstr[0] != '$') { + LogError(0, RS_RET_VALUE_NOT_SUPPORTED, + "mmsequence: valid variable name should start with $," + "got %s", cstr); + free(cstr); + } else { + pData->pszVar = cstr; + } + continue; + } + dbgprintf("mmsequence: program error, non-handled " + "param '%s'\n", actpblk.descr[i].name); + } + switch(pData->mode) { + case mmSequenceRandom: + pData->seed = (unsigned int)(intptr_t)pData ^ (unsigned int)time(NULL); + break; + case mmSequencePerInstance: + pData->value = pData->valueTo; + break; + case mmSequencePerKey: + if (pthread_mutex_lock(&ght_mutex)) { + DBGPRINTF("mmsequence: mutex lock has failed!\n"); + ABORT_FINALIZE(RS_RET_ERR); + } + if (ght == NULL) { + if(NULL == (ght = create_hashtable(100, hash_from_string, key_equals_string, NULL))) { + pthread_mutex_unlock(&ght_mutex); + DBGPRINTF("mmsequence: error creating hash table!\n"); + ABORT_FINALIZE(RS_RET_ERR); + } + } + pthread_mutex_unlock(&ght_mutex); + break; + default: + LogError(0, RS_RET_INVLD_MODE, + "mmsequence: this mode is not currently implemented"); + } + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +static int * +getCounter(struct hashtable *ht, char *str, int initial) { + int *pCounter; + char *pStr; + + pCounter = hashtable_search(ht, str); + if(pCounter) { + return pCounter; + } + + /* counter is not found for the str, so add new entry and + return the counter */ + if(NULL == (pStr = strdup(str))) { + DBGPRINTF("mmsequence: memory allocation for key failed\n"); + return NULL; + } + + if(NULL == (pCounter = (int*)malloc(sizeof(*pCounter)))) { + DBGPRINTF("mmsequence: memory allocation for value failed\n"); + free(pStr); + return NULL; + } + *pCounter = initial; + + if(!hashtable_insert(ht, pStr, pCounter)) { + DBGPRINTF("mmsequence: inserting element into hashtable failed\n"); + free(pStr); + free(pCounter); + return NULL; + } + return pCounter; +} + + +BEGINdoAction_NoStrings + smsg_t **ppMsg = (smsg_t **) pMsgData; + smsg_t *pMsg = ppMsg[0]; + struct json_object *json; + int val = 0; + int *pCounter; + instanceData *pData; +CODESTARTdoAction + pData = pWrkrData->pData; + + switch(pData->mode) { + case mmSequenceRandom: + val = pData->valueFrom + (rand_r(&pData->seed) % + (pData->valueTo - pData->valueFrom)); + break; + case mmSequencePerInstance: + if (!pthread_mutex_lock(&inst_mutex)) { + if (pData->value >= pData->valueTo - pData->step) { + pData->value = pData->valueFrom; + } else { + pData->value += pData->step; + } + val = pData->value; + pthread_mutex_unlock(&inst_mutex); + } else { + LogError(0, RS_RET_ERR, + "mmsequence: mutex lock has failed!"); + } + break; + case mmSequencePerKey: + if (!pthread_mutex_lock(&ght_mutex)) { + pCounter = getCounter(ght, pData->pszKey, pData->valueTo); + if(pCounter) { + if (*pCounter >= pData->valueTo - pData->step + || *pCounter < pData->valueFrom ) { + *pCounter = pData->valueFrom; + } else { + *pCounter += pData->step; + } + val = *pCounter; + } else { + LogError(0, RS_RET_NOT_FOUND, + "mmsequence: unable to fetch the counter from hash"); + } + pthread_mutex_unlock(&ght_mutex); + } else { + LogError(0, RS_RET_ERR, + "mmsequence: mutex lock has failed!"); + } + + break; + default: + LogError(0, RS_RET_NOT_IMPLEMENTED, + "mmsequence: this mode is not currently implemented"); + } + + /* finalize_it: */ + json = json_object_new_int(val); + if (json == NULL) { + LogError(0, RS_RET_OBJ_CREATION_FAILED, + "mmsequence: unable to create JSON"); + } else if (RS_RET_OK != msgAddJSON(pMsg, (uchar *)pData->pszVar + 1, json, 0, 0)) { + LogError(0, RS_RET_OBJ_CREATION_FAILED, + "mmsequence: unable to pass out the value"); + json_object_put(json); + } +ENDdoAction + + +NO_LEGACY_CONF_parseSelectorAct + + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +ENDqueryEtryPt + + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmsequence: module compiled with rsyslog version %s.\n", VERSION); +ENDmodInit diff --git a/contrib/mmtaghostname/Makefile.am b/contrib/mmtaghostname/Makefile.am new file mode 100644 index 0000000..5ba01ae --- /dev/null +++ b/contrib/mmtaghostname/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmtaghostname.la + +mmtaghostname_la_SOURCES = mmtaghostname.c +mmtaghostname_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmtaghostname_la_LDFLAGS = -module -avoid-version +mmtaghostname_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/mmtaghostname/Makefile.in b/contrib/mmtaghostname/Makefile.in new file mode 100644 index 0000000..bb9ad5d --- /dev/null +++ b/contrib/mmtaghostname/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/mmtaghostname +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +mmtaghostname_la_DEPENDENCIES = +am_mmtaghostname_la_OBJECTS = mmtaghostname_la-mmtaghostname.lo +mmtaghostname_la_OBJECTS = $(am_mmtaghostname_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +mmtaghostname_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(mmtaghostname_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(mmtaghostname_la_SOURCES) +DIST_SOURCES = $(mmtaghostname_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = mmtaghostname.la +mmtaghostname_la_SOURCES = mmtaghostname.c +mmtaghostname_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmtaghostname_la_LDFLAGS = -module -avoid-version +mmtaghostname_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmtaghostname/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/mmtaghostname/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +mmtaghostname.la: $(mmtaghostname_la_OBJECTS) $(mmtaghostname_la_DEPENDENCIES) $(EXTRA_mmtaghostname_la_DEPENDENCIES) + $(AM_V_CCLD)$(mmtaghostname_la_LINK) -rpath $(pkglibdir) $(mmtaghostname_la_OBJECTS) $(mmtaghostname_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mmtaghostname_la-mmtaghostname.lo: mmtaghostname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmtaghostname_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmtaghostname_la-mmtaghostname.lo -MD -MP -MF $(DEPDIR)/mmtaghostname_la-mmtaghostname.Tpo -c -o mmtaghostname_la-mmtaghostname.lo `test -f 'mmtaghostname.c' || echo '$(srcdir)/'`mmtaghostname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmtaghostname_la-mmtaghostname.Tpo $(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmtaghostname.c' object='mmtaghostname_la-mmtaghostname.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmtaghostname_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmtaghostname_la-mmtaghostname.lo `test -f 'mmtaghostname.c' || echo '$(srcdir)/'`mmtaghostname.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/mmtaghostname/mmtaghostname.c b/contrib/mmtaghostname/mmtaghostname.c new file mode 100644 index 0000000..ae72252 --- /dev/null +++ b/contrib/mmtaghostname/mmtaghostname.c @@ -0,0 +1,205 @@ +/* mmtaghostname.c + * This is a message modification module. + * + * The name of the module is inspired by the parser module pmnull + * Its objectives are closed to this parser but as a message modification + * it can be used in a different step of the message processing without + * interfering in the parser chain process and can be applied before or + * after parsing process. + * + * Its purposes are : + * - to add a tag on message produce by input module which does not provide + * a tag like imudp or imtcp. Useful when the tag is used for routing the + * message. + * - to force message hostname to the rsyslog valeur. The use case is + * application in auto-scaling systems (AWS) providing logs through udp/tcp + * were the name of the host is based on an ephemeral IPs with a short term + * meaning. In this situation rsyslog local host name is generally the + * auto-scaling name then logs produced by the application is affected to + * the application instead of the ephemeral VM. + * + * + * This file is a contribution of rsyslog. + * + * Author : Ph. Duveau <philippe.duveau@free.fr> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <ctype.h> + +#include "rsyslog.h" +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "dirty.h" +#include "unicode-helper.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("mmtaghostname") + +/* internal structures */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(glbl) + +/* parser instance parameters */ +static struct cnfparamdescr parserpdescr[] = { + { "tag", eCmdHdlrString, 0 }, + { "forcelocalhostname", eCmdHdlrBinary, 0 }, +}; +static struct cnfparamblk parserpblk = + { CNFPARAMBLK_VERSION, + sizeof(parserpdescr)/sizeof(struct cnfparamdescr), + parserpdescr + }; + +typedef struct _instanceData { + char *pszTag; + size_t lenTag; + int bForceLocalHostname; +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; +} wrkrInstanceData_t; + +static const uchar *pszHostname = NULL; +static size_t lenHostname = 0; + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + dbgprintf("mmtaghostname:\n"); + dbgprintf("\ttag='%s'\n", pData->pszTag); + dbgprintf("\tforce local hostname='%d'\n", pData->bForceLocalHostname); +ENDdbgPrintInstInfo + +BEGINcreateInstance +CODESTARTcreateInstance + pData->pszTag = NULL; + pData->lenTag = 0; + pData->bForceLocalHostname = 0; +ENDcreateInstance + +BEGINfreeInstance +CODESTARTfreeInstance + free(pData->pszTag); +ENDfreeInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + +BEGINnewActInst + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTnewActInst + DBGPRINTF("newParserInst (mmtaghostname)\n"); + + CHKiRet(createInstance(&pData)); + + if(lst == NULL) + FINALIZE; /* just set defaults, no param block! */ + + if((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("parser param blk in mmtaghostname:\n"); + cnfparamsPrint(&parserpblk, pvals); + } + + for(i = 0 ; i < parserpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(parserpblk.descr[i].name, "tag")) { + pData->pszTag = (char *) es_str2cstr(pvals[i].val.d.estr, NULL); + pData->lenTag = strlen(pData->pszTag); + } else if(!strcmp(parserpblk.descr[i].name, "forcelocalhostname")) { + pData->bForceLocalHostname = pvals[i].val.d.n; + } else { + dbgprintf("program error, non-handled param '%s'\n", + parserpblk.descr[i].name); + } + } + CODE_STD_STRING_REQUESTnewActInst(1) + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); +CODE_STD_FINALIZERnewActInst + if(lst != NULL) + cnfparamvalsDestruct(pvals, &parserpblk); +ENDnewActInst + +BEGINdoAction_NoStrings + smsg_t **ppMsg = (smsg_t **) pMsgData; + smsg_t *pMsg = ppMsg[0]; + instanceData *pData = pWrkrData->pData; +CODESTARTdoAction + DBGPRINTF("Message will now be managed by mmtaghostname\n"); + if(pData->pszTag != NULL) { + MsgSetTAG(pMsg, (uchar *)pData->pszTag, pData->lenTag); + } + if (pData->bForceLocalHostname) { + if (pszHostname == NULL) { + pszHostname = glbl.GetLocalHostName(); + lenHostname = ustrlen(glbl.GetLocalHostName()); + } + MsgSetHOSTNAME(pMsg, pszHostname, lenHostname); + DBGPRINTF("Message hostname forced to local\n"); + } +ENDdoAction + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +BEGINparseSelectorAct +CODESTARTparseSelectorAct +CODE_STD_FINALIZERparseSelectorAct +ENDparseSelectorAct + +BEGINmodExit +CODESTARTmodExit + objRelease(glbl, CORE_COMPONENT); +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); +ENDmodInit diff --git a/contrib/omamqp1/Makefile.am b/contrib/omamqp1/Makefile.am new file mode 100644 index 0000000..8cc3b0b --- /dev/null +++ b/contrib/omamqp1/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = omamqp1.la + +omamqp1_la_SOURCES = omamqp1.c +omamqp1_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(PROTON_CFLAGS) +omamqp1_la_LDFLAGS = -module -avoid-version +omamqp1_la_LIBADD = $(PROTON_LIBS) $(PTHREADS_LIBS) + +EXTRA_DIST = diff --git a/contrib/omamqp1/Makefile.in b/contrib/omamqp1/Makefile.in new file mode 100644 index 0000000..5b86d3a --- /dev/null +++ b/contrib/omamqp1/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omamqp1 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +omamqp1_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_omamqp1_la_OBJECTS = omamqp1_la-omamqp1.lo +omamqp1_la_OBJECTS = $(am_omamqp1_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omamqp1_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(omamqp1_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/omamqp1_la-omamqp1.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omamqp1_la_SOURCES) +DIST_SOURCES = $(omamqp1_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omamqp1.la +omamqp1_la_SOURCES = omamqp1.c +omamqp1_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(PROTON_CFLAGS) +omamqp1_la_LDFLAGS = -module -avoid-version +omamqp1_la_LIBADD = $(PROTON_LIBS) $(PTHREADS_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omamqp1/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omamqp1/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omamqp1.la: $(omamqp1_la_OBJECTS) $(omamqp1_la_DEPENDENCIES) $(EXTRA_omamqp1_la_DEPENDENCIES) + $(AM_V_CCLD)$(omamqp1_la_LINK) -rpath $(pkglibdir) $(omamqp1_la_OBJECTS) $(omamqp1_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omamqp1_la-omamqp1.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omamqp1_la-omamqp1.lo: omamqp1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omamqp1_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omamqp1_la-omamqp1.lo -MD -MP -MF $(DEPDIR)/omamqp1_la-omamqp1.Tpo -c -o omamqp1_la-omamqp1.lo `test -f 'omamqp1.c' || echo '$(srcdir)/'`omamqp1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omamqp1_la-omamqp1.Tpo $(DEPDIR)/omamqp1_la-omamqp1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omamqp1.c' object='omamqp1_la-omamqp1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omamqp1_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omamqp1_la-omamqp1.lo `test -f 'omamqp1.c' || echo '$(srcdir)/'`omamqp1.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omamqp1_la-omamqp1.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omamqp1_la-omamqp1.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omamqp1/omamqp1.c b/contrib/omamqp1/omamqp1.c new file mode 100644 index 0000000..38d0022 --- /dev/null +++ b/contrib/omamqp1/omamqp1.c @@ -0,0 +1,921 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * + * omamqp1.c + * + * This output plugin enables rsyslog to send messages to an AMQP 1.0 protocol + * compliant message bus. + * + * AMQP glue code Copyright (C) 2015-2016 Kenneth A. Giusti + * <kgiusti@gmail.com> + */ + +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" + +#include <pthread.h> +#include <time.h> +#include <proton/reactor.h> +#include <proton/handlers.h> +#include <proton/event.h> +#include <proton/connection.h> +#include <proton/session.h> +#include <proton/link.h> +#include <proton/delivery.h> +#include <proton/message.h> +#include <proton/transport.h> +#include <proton/sasl.h> +#include <proton/url.h> +#include <proton/version.h> + + +/* work-around issues in this contributed module */ +#pragma GCC diagnostic ignored "-Wswitch-enum" +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omamqp1") + + +/* internal structures + */ +DEF_OMOD_STATIC_DATA + + +/* Settings for the action */ +typedef struct _configSettings { + pn_url_t *url; /* address of message bus */ + uchar *username; /* authentication credentials */ + uchar *password; + uchar *target; /* endpoint for sent log messages */ + uchar *templateName; + int bDisableSASL; /* do not enable SASL? 0-enable 1-disable */ + int idleTimeout; /* disconnect idle connection (seconds) */ + int reconnectDelay; /* pause before re-connecting (seconds) */ + int maxRetries; /* drop unrouteable messages after maxRetries attempts */ +} configSettings_t; + + +/* Control for communicating with the protocol engine thread */ + +typedef enum { // commands sent to protocol thread + COMMAND_DONE, // marks command complete + COMMAND_SEND, // send a message to the message bus + COMMAND_IS_READY, // is the connection to the message bus active? + COMMAND_SHUTDOWN // cleanup and terminate protocol thread. +} commands_t; + + +typedef struct _threadIPC { + pthread_mutex_t lock; + pthread_cond_t condition; + commands_t command; + rsRetVal result; // of command + pn_message_t *message; + uint64_t tag; // per message id +} threadIPC_t; + + +/* per-instance data */ + +typedef struct _instanceData { + configSettings_t config; + threadIPC_t ipc; + int bThreadRunning; + pthread_t thread_id; + pn_reactor_t *reactor; + pn_handler_t *handler; + pn_message_t *message; + int log_count; +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; +} wrkrInstanceData_t; + + +/* glue code */ + +typedef void dispatch_t(pn_handler_t *, pn_event_t *, pn_event_type_t); + +static void _init_thread_ipc(threadIPC_t *pIPC); +static void _clean_thread_ipc(threadIPC_t *ipc); +static void _init_config_settings(configSettings_t *pConfig); +static void _clean_config_settings(configSettings_t *pConfig); +static rsRetVal _shutdown_thread(instanceData *pData); +static rsRetVal _new_handler(pn_handler_t **handler, + pn_reactor_t *reactor, + dispatch_t *dispatcher, + configSettings_t *config, + threadIPC_t *ipc); +static void _del_handler(pn_handler_t *handler); +static rsRetVal _launch_protocol_thread(instanceData *pData); +static rsRetVal _shutdown_thread(instanceData *pData); +static rsRetVal _issue_command(threadIPC_t *ipc, + pn_reactor_t *reactor, + commands_t command, + pn_message_t *message); +static void dispatcher(pn_handler_t *handler, + pn_event_t *event, + pn_event_type_t type); + + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "host", eCmdHdlrGetWord, CNFPARAM_REQUIRED }, + { "target", eCmdHdlrGetWord, CNFPARAM_REQUIRED }, + { "username", eCmdHdlrGetWord, 0 }, + { "password", eCmdHdlrGetWord, 0 }, + { "template", eCmdHdlrGetWord, 0 }, + { "idleTimeout", eCmdHdlrNonNegInt, 0 }, + { "reconnectDelay", eCmdHdlrPositiveInt, 0 }, + { "maxRetries", eCmdHdlrNonNegInt, 0 }, + { "disableSASL", eCmdHdlrInt, 0 } +}; +static struct cnfparamblk actpblk = { + CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr +}; + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +{ + if (eFeat == sFEATURERepeatedMsgReduction) + iRet = RS_RET_OK; +} +ENDisCompatibleWithFeature + + +BEGINcreateInstance +CODESTARTcreateInstance +{ + memset(pData, 0, sizeof(instanceData)); + _init_config_settings(&pData->config); + _init_thread_ipc(&pData->ipc); +} +ENDcreateInstance + + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + + +BEGINfreeInstance +CODESTARTfreeInstance +{ + _shutdown_thread(pData); + _clean_config_settings(&pData->config); + _clean_thread_ipc(&pData->ipc); + if (pData->reactor) pn_reactor_free(pData->reactor); + if (pData->handler) pn_handler_free(pData->handler); + if (pData->message) pn_message_free(pData->message); +} +ENDfreeInstance + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +{ + configSettings_t *cfg = &pData->config; + dbgprintf("omamqp1:\n"); + dbgprintf(" host=%s\n", pn_url_str(cfg->url)); + dbgprintf(" username=%s\n", cfg->username); + //dbgprintf(" password=%s\n", pData->password); + dbgprintf(" target=%s\n", cfg->target); + dbgprintf(" template=%s\n", cfg->templateName); + dbgprintf(" disableSASL=%d\n", cfg->bDisableSASL); + dbgprintf(" idleTimeout=%d\n", cfg->idleTimeout); + dbgprintf(" reconnectDelay=%d\n", cfg->reconnectDelay); + dbgprintf(" maxRetries=%d\n", cfg->maxRetries); + dbgprintf(" running=%d\n", pData->bThreadRunning); +} +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume +{ + // is the link active? + instanceData *pData = pWrkrData->pData; + iRet = _issue_command(&pData->ipc, pData->reactor, COMMAND_IS_READY, NULL); +} +ENDtryResume + + +BEGINbeginTransaction +CODESTARTbeginTransaction +{ + DBGPRINTF("omamqp1: beginTransaction\n"); + instanceData *pData = pWrkrData->pData; + pData->log_count = 0; + if (pData->message) pn_message_free(pData->message); + pData->message = pn_message(); + CHKmalloc(pData->message); + pn_data_t *body = pn_message_body(pData->message); + pn_data_put_list(body); + pn_data_enter(body); +} +finalize_it: +ENDbeginTransaction + + +BEGINdoAction +CODESTARTdoAction +{ + DBGPRINTF("omamqp1: doAction\n"); + instanceData *pData = pWrkrData->pData; + if (!pData->message) ABORT_FINALIZE(RS_RET_OK); + pn_bytes_t msg = pn_bytes(strlen((const char *)ppString[0]), + (const char *)ppString[0]); + pn_data_t *body = pn_message_body(pData->message); + pn_data_put_string(body, msg); + pData->log_count++; + iRet = RS_RET_DEFER_COMMIT; +} +finalize_it: +ENDdoAction + + +BEGINendTransaction +CODESTARTendTransaction +{ + DBGPRINTF("omamqp1: endTransaction\n"); + instanceData *pData = pWrkrData->pData; + if (!pData->message) ABORT_FINALIZE(RS_RET_OK); + pn_data_t *body = pn_message_body(pData->message); + pn_data_exit(body); + pn_message_t *message = pData->message; + pData->message = NULL; + if (pData->log_count > 0) { + DBGPRINTF("omamqp1: sending [%d] records\n", pData->log_count); + CHKiRet(_issue_command(&pData->ipc, pData->reactor, COMMAND_SEND, message)); + } else { + DBGPRINTF("omamqp1: no log messages to send\n"); + pn_message_free(message); + } +} +finalize_it: +ENDendTransaction + + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; + configSettings_t *cs; +CODESTARTnewActInst +{ + if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CHKiRet(createInstance(&pData)); + cs = &pData->config; + + CODE_STD_STRING_REQUESTnewActInst(1); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if (!pvals[i].bUsed) + continue; + if (!strcmp(actpblk.descr[i].name, "host")) { + char *u = es_str2cstr(pvals[i].val.d.estr, NULL); + cs->url = pn_url_parse(u); + if (!cs->url) { + LogError(0, RS_RET_CONF_PARSE_ERROR, "omamqp1: Invalid host URL configured: '%s'", u); + free(u); + ABORT_FINALIZE(RS_RET_CONF_PARSE_ERROR); + } + free(u); + } else if (!strcmp(actpblk.descr[i].name, "template")) { + cs->templateName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "target")) { + cs->target = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "username")) { + cs->username = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "password")) { + cs->password = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "reconnectDelay")) { + cs->reconnectDelay = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "idleTimeout")) { + cs->idleTimeout = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "maxRetries")) { + cs->maxRetries = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "disableSASL")) { + cs->bDisableSASL = (int) pvals[i].val.d.n; + } else { + dbgprintf("omamqp1: program error, unrecognized param '%s', ignored.\n", + actpblk.descr[i].name); + } + } + + CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar*)strdup((cs->templateName == NULL) + ? "RSYSLOG_FileFormat" : (char*)cs->templateName), OMSR_NO_RQD_TPL_OPTS)); + + // once configuration is known, start the protocol engine thread + pData->reactor = pn_reactor(); + CHKmalloc(pData->reactor); + CHKiRet(_new_handler(&pData->handler, pData->reactor, dispatcher, &pData->config, &pData->ipc)); + CHKiRet(_launch_protocol_thread(pData)); +} +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + + +NO_LEGACY_CONF_parseSelectorAct + + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt + CODESTARTqueryEtryPt + CODEqueryEtryPt_STD_OMOD_QUERIES + CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES + CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES + CODEqueryEtryPt_TXIF_OMOD_QUERIES /* use transaction interface */ + CODEqueryEtryPt_STD_OMOD8_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit +{ + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current + interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); + DBGPRINTF("omamqp1: module compiled with rsyslog version %s.\n", VERSION); + DBGPRINTF("omamqp1: %susing transactional output interface.\n", bCoreSupportsBatching ? "" : "not "); +} +ENDmodInit + + +/////////////////////////////////////// +// All the Proton-specific glue code // +/////////////////////////////////////// + + +/* state maintained by the protocol thread */ + +typedef struct { + const configSettings_t *config; + threadIPC_t *ipc; + pn_reactor_t *reactor; // AMQP 1.0 protocol engine + pn_connection_t *conn; + pn_link_t *sender; + pn_delivery_t *delivery; + char *encode_buffer; + size_t buffer_size; + uint64_t tag; + int msgs_sent; + int msgs_settled; + int retries; + sbool stopped; +} protocolState_t; + +// protocolState_t is embedded in the engine handler +#define PROTOCOL_STATE(eh) ((protocolState_t *) pn_handler_mem(eh)) + + +static void _init_config_settings(configSettings_t *pConfig) +{ + memset(pConfig, 0, sizeof(configSettings_t)); + pConfig->reconnectDelay = 5; + pConfig->maxRetries = 10; +} + + +static void _clean_config_settings(configSettings_t *pConfig) +{ + if (pConfig->url) pn_url_free(pConfig->url); + if (pConfig->username) free(pConfig->username); + if (pConfig->password) free(pConfig->password); + if (pConfig->target) free(pConfig->target); + if (pConfig->templateName) free(pConfig->templateName); + memset(pConfig, 0, sizeof(configSettings_t)); +} + + +static void _init_thread_ipc(threadIPC_t *pIPC) +{ + memset(pIPC, 0, sizeof(threadIPC_t)); + pthread_mutex_init(&pIPC->lock, NULL); + pthread_cond_init(&pIPC->condition, NULL); + pIPC->command = COMMAND_DONE; + pIPC->result = RS_RET_OK; +} + +static void _clean_thread_ipc(threadIPC_t *ipc) +{ + pthread_cond_destroy(&ipc->condition); + pthread_mutex_destroy(&ipc->lock); +} + + +// create a new handler for the engine and set up the protocolState +static rsRetVal _new_handler(pn_handler_t **handler, + pn_reactor_t *reactor, + dispatch_t *dispatch, + configSettings_t *config, + threadIPC_t *ipc) +{ + DEFiRet; + *handler = pn_handler_new(dispatch, sizeof(protocolState_t), _del_handler); + CHKmalloc(*handler); + pn_handler_add(*handler, pn_handshaker()); + protocolState_t *pState = PROTOCOL_STATE(*handler); + memset(pState, 0, sizeof(protocolState_t)); + pState->buffer_size = 64; // will grow if not enough + pState->encode_buffer = (char *)malloc(pState->buffer_size); + CHKmalloc(pState->encode_buffer); + pState->reactor = reactor; + pState->stopped = false; + // these are _references_, don't free them: + pState->config = config; + pState->ipc = ipc; + +finalize_it: + RETiRet; +} + + +// in case existing buffer too small +static rsRetVal _grow_buffer(protocolState_t *pState) +{ + DEFiRet; + pState->buffer_size *= 2; + free(pState->encode_buffer); + pState->encode_buffer = (char *)malloc(pState->buffer_size); + CHKmalloc(pState->encode_buffer); + +finalize_it: + RETiRet; +} + + +/* release the pn_handler_t instance. Do not call this directly, + * it will be called by the reactor when all references to the + * handler have been released. + */ +static void _del_handler(pn_handler_t *handler) +{ + protocolState_t *pState = PROTOCOL_STATE(handler); + if (pState->encode_buffer) free(pState->encode_buffer); +} + + +// Close the sender and its parent session and connection +static void _close_connection(protocolState_t *ps) +{ + if (ps->sender) { + pn_link_close(ps->sender); + pn_session_close(pn_link_session(ps->sender)); + } + if (ps->conn) pn_connection_close(ps->conn); +} + +static void _abort_command(protocolState_t *ps) +{ + threadIPC_t *ipc = ps->ipc; + + pthread_mutex_lock(&ipc->lock); + switch (ipc->command) { + case COMMAND_SEND: + dbgprintf("omamqp1: aborted the message send in progress\n"); + CASE_FALLTHROUGH + case COMMAND_IS_READY: + ipc->result = RS_RET_SUSPENDED; + ipc->command = COMMAND_DONE; + pthread_cond_signal(&ipc->condition); + break; + case COMMAND_SHUTDOWN: // cannot be aborted + case COMMAND_DONE: + break; + } + pthread_mutex_unlock(&ipc->lock); +} + + +// log a protocol error received from the message bus +static void _log_error(const char *message, pn_condition_t *cond) +{ + const char *name = pn_condition_get_name(cond); + const char *desc = pn_condition_get_description(cond); + dbgprintf("omamqp1: %s %s:%s\n", + message, + (name) ? name : "<no name>", + (desc) ? desc : "<no description>"); +} + + +/* is the link ready to send messages? */ +static sbool _is_ready(pn_link_t *link) +{ + return (link + && pn_link_state(link) == (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE) + && pn_link_credit(link) > 0); +} + + +/* Process each event emitted by the protocol engine */ +static void dispatcher(pn_handler_t *handler, pn_event_t *event, pn_event_type_t type) +{ + protocolState_t *ps = PROTOCOL_STATE(handler); + const configSettings_t *cfg = ps->config; + + //DBGPRINTF("omamqp1: Event received: %s\n", pn_event_type_name(type)); + + switch (type) { + + case PN_LINK_REMOTE_OPEN: + DBGPRINTF("omamqp1: Message bus opened link.\n"); + break; + + case PN_DELIVERY: + // has the message been delivered to the message bus? + if (ps->delivery) { + assert(ps->delivery == pn_event_delivery(event)); + if (pn_delivery_updated(ps->delivery)) { + rsRetVal result = RS_RET_IDLE; + uint64_t rs = pn_delivery_remote_state(ps->delivery); + switch (rs) { + case PN_ACCEPTED: + DBGPRINTF("omamqp1: Message ACCEPTED by message bus\n"); + result = RS_RET_OK; + break; + case PN_REJECTED: + dbgprintf("omamqp1: message bus rejected log message: invalid message - dropping\n"); + // message bus considers this a 'bad message'. Cannot be redelivered. + // Likely a configuration error. Drop the message by returning OK + result = RS_RET_OK; + break; + case PN_RELEASED: + case PN_MODIFIED: + // the message bus cannot accept the message. This may be temporary - retry + // up to maxRetries before dropping + if (++ps->retries >= cfg->maxRetries) { + dbgprintf("omamqp1: message bus failed to accept message - dropping\n"); + result = RS_RET_OK; + } else { + dbgprintf("omamqp1: message bus cannot accept message, retrying\n"); + result = RS_RET_SUSPENDED; + } + break; + case PN_RECEIVED: + // not finished yet, wait for next delivery update + break; + default: + // no other terminal states defined, so ignore anything else + dbgprintf("omamqp1: unknown delivery state=0x%lX, assuming message accepted\n", + (unsigned long) pn_delivery_remote_state(ps->delivery)); + result = RS_RET_OK; + break; + } + + if (result != RS_RET_IDLE) { + // the command is complete + threadIPC_t *ipc = ps->ipc; + pthread_mutex_lock(&ipc->lock); + assert(ipc->command == COMMAND_SEND); + ipc->result = result; + ipc->command = COMMAND_DONE; + pthread_cond_signal(&ipc->condition); + pthread_mutex_unlock(&ipc->lock); + pn_delivery_settle(ps->delivery); + ps->delivery = NULL; + if (result == RS_RET_OK) { + ps->retries = 0; + } + } + } + } + break; + + + case PN_CONNECTION_BOUND: + if (!cfg->bDisableSASL) { + // force use of SASL, even allowing PLAIN authentication + pn_sasl_t *sasl = pn_sasl(pn_event_transport(event)); +#if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 10 + pn_sasl_set_allow_insecure_mechs(sasl, true); +#else + // proton version <= 0.9 only supports PLAIN authentication + const char *user = cfg->username + ? (char *)cfg->username + : pn_url_get_username(cfg->url); + if (user) { + pn_sasl_plain(sasl, user, (cfg->password + ? (char *) cfg->password + : pn_url_get_password(cfg->url))); + } +#endif + } + if (cfg->idleTimeout) { + // configured as seconds, set as milliseconds + pn_transport_set_idle_timeout(pn_event_transport(event), + cfg->idleTimeout * 1000); + } + break; + + case PN_CONNECTION_UNBOUND: + DBGPRINTF("omamqp1: cleaning up connection resources\n"); + pn_connection_release(pn_event_connection(event)); + ps->conn = NULL; + ps->sender = NULL; + ps->delivery = NULL; + break; + + + case PN_TRANSPORT_ERROR: + { + // TODO: if auth failure, does it make sense to retry??? + pn_transport_t *tport = pn_event_transport(event); + pn_condition_t *cond = pn_transport_condition(tport); + if (pn_condition_is_set(cond)) { + _log_error("transport failure", cond); + } + dbgprintf("omamqp1: network transport failed, reconnecting...\n"); + // the protocol thread will attempt to reconnect if it is not + // being shut down + } + break; + + default: + break; + } +} + + +// Send a command to the protocol thread and +// wait for the command to complete +static rsRetVal _issue_command(threadIPC_t *ipc, + pn_reactor_t *reactor, + commands_t command, + pn_message_t *message) +{ + DEFiRet; + + DBGPRINTF("omamqp1: Sending command %d to protocol thread\n", command); + + pthread_mutex_lock(&ipc->lock); + + if (message) { + assert(ipc->message == NULL); + ipc->message = message; + } + assert(ipc->command == COMMAND_DONE); + ipc->command = command; + pn_reactor_wakeup(reactor); + while (ipc->command != COMMAND_DONE) { + pthread_cond_wait(&ipc->condition, &ipc->lock); + } + iRet = ipc->result; + if (ipc->message) { + pn_message_free(ipc->message); + ipc->message = NULL; + } + + pthread_mutex_unlock(&ipc->lock); + + DBGPRINTF("omamqp1: Command %d completed, status=%d\n", command, iRet); + RETiRet; +} + + +// check if a command needs processing +static void _poll_command(protocolState_t *ps) +{ + if (ps->stopped) return; + + threadIPC_t *ipc = ps->ipc; + + pthread_mutex_lock(&ipc->lock); + + switch (ipc->command) { + + case COMMAND_SHUTDOWN: + DBGPRINTF("omamqp1: Protocol thread processing shutdown command\n"); + ps->stopped = true; + _close_connection(ps); + // wait for the shutdown to complete before ack'ing this command + break; + + case COMMAND_IS_READY: + DBGPRINTF("omamqp1: Protocol thread processing ready query command\n"); + ipc->result = _is_ready(ps->sender) + ? RS_RET_OK + : RS_RET_SUSPENDED; + ipc->command = COMMAND_DONE; + pthread_cond_signal(&ipc->condition); + break; + + case COMMAND_SEND: + if (ps->delivery) break; // currently processing this command + DBGPRINTF("omamqp1: Protocol thread processing send message command\n"); + if (!_is_ready(ps->sender)) { + ipc->result = RS_RET_SUSPENDED; + ipc->command = COMMAND_DONE; + pthread_cond_signal(&ipc->condition); + break; + } + + // send the message + ++ps->tag; + ps->delivery = pn_delivery(ps->sender, + pn_dtag((const char *)&ps->tag, sizeof(ps->tag))); + pn_message_t *message = ipc->message; + assert(message); + + int rc = 0; + size_t len = ps->buffer_size; + do { + rc = pn_message_encode(message, ps->encode_buffer, &len); + if (rc == PN_OVERFLOW) { + _grow_buffer(ps); + len = ps->buffer_size; + } + } while (rc == PN_OVERFLOW); + + pn_link_send(ps->sender, ps->encode_buffer, len); + pn_link_advance(ps->sender); + ++ps->msgs_sent; + // command completes when remote updates the delivery (see PN_DELIVERY) + break; + + case COMMAND_DONE: + break; + } + + pthread_mutex_unlock(&ipc->lock); +} + +/* runs the protocol engine, allowing it to handle TCP socket I/O and timer + * events in the background. +*/ +static void *amqp1_thread(void *arg) +{ + + pn_handler_t *handler = (pn_handler_t *)arg; + protocolState_t *ps = PROTOCOL_STATE(handler); + const configSettings_t *cfg = ps->config; + + // have pn_reactor_process() exit after 5 sec to poll for commands + pn_reactor_set_timeout(ps->reactor, 5000); + pn_reactor_start(ps->reactor); + + while (!ps->stopped) { + // setup a connection: + const char *host = pn_url_get_host(cfg->url); + const char *port = pn_url_get_port(cfg->url); + if (!port) port = "5672"; + +#if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 13 + ps->conn = pn_reactor_connection_to_host(ps->reactor, + host, + port, + handler); + pn_connection_set_hostname(ps->conn, host); +#else + { + char host_addr[300]; + ps->conn = pn_reactor_connection(ps->reactor, handler); + snprintf(host_addr, sizeof(host_addr), "%s:%s", host, port); + pn_connection_set_hostname(ps->conn, host_addr); + } +#endif + pn_connection_set_container(ps->conn, "rsyslogd-omamqp1"); + +#if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 10 + // proton version <= 0.9 did not support Cyrus SASL + const char *user = cfg->username + ? (char *)cfg->username + : pn_url_get_username(cfg->url); + if (user) + pn_connection_set_user(ps->conn, user); + + const char *pword = cfg->password + ? (char *) cfg->password + : pn_url_get_password(cfg->url); + if (pword) + pn_connection_set_password(ps->conn, pword); +#endif + pn_connection_open(ps->conn); + pn_session_t *ssn = pn_session(ps->conn); + pn_session_open(ssn); + ps->sender = pn_sender(ssn, (char *)cfg->target); + pn_link_set_snd_settle_mode(ps->sender, PN_SND_UNSETTLED); + char *addr = (char *)ps->config->target; + pn_terminus_set_address(pn_link_target(ps->sender), addr); + pn_terminus_set_address(pn_link_source(ps->sender), addr); + pn_link_open(ps->sender); + + // run the protocol engine until the connection closes or thread is shut down + sbool engine_running = true; + while (engine_running) { + engine_running = pn_reactor_process(ps->reactor); + _poll_command(ps); + } + + _abort_command(ps); // unblock main thread if necessary + + // delay reconnectDelay seconds before re-connecting: + int delay = ps->config->reconnectDelay; + while (delay-- > 0 && !ps->stopped) { + srSleep(1, 0); + _poll_command(ps); + } + } + pn_reactor_stop(ps->reactor); + // stop command is now done: + threadIPC_t *ipc = ps->ipc; + pthread_mutex_lock(&ipc->lock); + ipc->result = RS_RET_OK; + ipc->command = COMMAND_DONE; + pthread_cond_signal(&ipc->condition); + pthread_mutex_unlock(&ipc->lock); + + DBGPRINTF("omamqp1: Protocol thread stopped\n"); + + return 0; +} + + +static rsRetVal _launch_protocol_thread(instanceData *pData) +{ + int rc; + DBGPRINTF("omamqp1: Starting protocol thread\n"); + do { + rc = pthread_create(&pData->thread_id, NULL, amqp1_thread, pData->handler); + if (!rc) { + pData->bThreadRunning = true; + return RS_RET_OK; + } + } while (rc == EAGAIN); + LogError(0, RS_RET_SYS_ERR, "omamqp1: thread create failed: %d", rc); + return RS_RET_SYS_ERR; +} + +static rsRetVal _shutdown_thread(instanceData *pData) +{ + DEFiRet; + + if (pData->bThreadRunning) { + DBGPRINTF("omamqp1: shutting down thread...\n"); + CHKiRet(_issue_command(&pData->ipc, pData->reactor, COMMAND_SHUTDOWN, NULL)); + pthread_join(pData->thread_id, NULL); + pData->bThreadRunning = false; + DBGPRINTF("omamqp1: thread shutdown complete\n"); + } + +finalize_it: + RETiRet; +} + + + +/* vi:set ai: + */ + diff --git a/contrib/omczmq/Makefile.am b/contrib/omczmq/Makefile.am new file mode 100644 index 0000000..d2b09bd --- /dev/null +++ b/contrib/omczmq/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = omczmq.la + +omczmq_la_SOURCES = omczmq.c +omczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) +omczmq_la_LDFLAGS = -module -avoid-version +omczmq_la_LIBADD = $(CZMQ_LIBS) + +EXTRA_DIST = diff --git a/contrib/omczmq/Makefile.in b/contrib/omczmq/Makefile.in new file mode 100644 index 0000000..cd0990e --- /dev/null +++ b/contrib/omczmq/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omczmq +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +omczmq_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_omczmq_la_OBJECTS = omczmq_la-omczmq.lo +omczmq_la_OBJECTS = $(am_omczmq_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omczmq_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(omczmq_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/omczmq_la-omczmq.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omczmq_la_SOURCES) +DIST_SOURCES = $(omczmq_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omczmq.la +omczmq_la_SOURCES = omczmq.c +omczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) +omczmq_la_LDFLAGS = -module -avoid-version +omczmq_la_LIBADD = $(CZMQ_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omczmq/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omczmq/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omczmq.la: $(omczmq_la_OBJECTS) $(omczmq_la_DEPENDENCIES) $(EXTRA_omczmq_la_DEPENDENCIES) + $(AM_V_CCLD)$(omczmq_la_LINK) -rpath $(pkglibdir) $(omczmq_la_OBJECTS) $(omczmq_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omczmq_la-omczmq.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omczmq_la-omczmq.lo: omczmq.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omczmq_la-omczmq.lo -MD -MP -MF $(DEPDIR)/omczmq_la-omczmq.Tpo -c -o omczmq_la-omczmq.lo `test -f 'omczmq.c' || echo '$(srcdir)/'`omczmq.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omczmq_la-omczmq.Tpo $(DEPDIR)/omczmq_la-omczmq.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omczmq.c' object='omczmq_la-omczmq.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omczmq_la-omczmq.lo `test -f 'omczmq.c' || echo '$(srcdir)/'`omczmq.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omczmq_la-omczmq.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omczmq_la-omczmq.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omczmq/README b/contrib/omczmq/README new file mode 100644 index 0000000..5399840 --- /dev/null +++ b/contrib/omczmq/README @@ -0,0 +1,79 @@ +CZMQ Output Plugin + +REQUIREMENTS: + +* libsodium ( https://github.com/jedisct1/libsodium ) +* zeromq built with libsodium support ( http://zeromq.org/ ) +* czmq ( http://czmq.zeromq.org/ ) + +EXPLANATION OF OPTIONS + +Module +------ +servercertpath: path to server cert if using CURVE +clientcertpath: path to client cert(s) if using CURVE +authtype: CURVESERVER, CURVECLIENT (omit for no auth) +authenticator: whether to start an authenticator thread + +Action +------ +type: type of action (omczmq for this plugin) +endpoints: comma delimited list of zeromq endpoints (see zeromq documentation) +socktype: zeromq socket type (currently supports PUSH, PUB, DEALER, RADIO, CLIENT, SCATTER) +sendtimeout: timeout in ms before send errors +sendhwm: number of messages to store in internal buffer before discarding (defaults to 1000) +connecttimeout: connection timeout in ms(requires libzmq 4.2 or higher) +heartbeativl: time in ms between sending heartbeat PING messages (requires libzmq 4.2 or higher) +heartbeattimeout: time in milliseconds to wait for a PING response before disconnect(libzmq 4.2 or higher) +heartbeatttl: time remote peer should wait between PINGs before disconnect (libzmq 4.2 or higher) +topicframe: "on" to send topic as separate frame if PUB socket +topics: comma delimited list of topics or templates to make topics from if PUB or RADIO socket +dynatopic: if "on" topics list is treated as list of template names +template: template to use for message (defaults to RSYSLOG_ForwardFormat) + +EXAMPLE CONFIGURATION + +This configuration sets up an omczmq endpoint as a ZMQ_PUB socket with CURVE authentication. +Clients whose certificates are in the '/etc/curve.d/allowed_clients/' directory will be +allowed to connect. Each message is published on two topics ( "hostname.programname" and +"programname.hostname" ) which are constructed from properties of the log message. + +For instance, a log from sshd from host.example.com will be published on two topics: + * host.example.com.sshd + * sshd.host.example.com + +In this configuration, the output is configured to send each message as a two frame +message, with the topic in the first flame and the rsyslog message in the second. + +------------------------------------------------------------------------------- +module( + load="omczmq" + servercertpath="/etc/curve.d/example_server" + clientcertpath="/etc/curve.d/allowed_clients" + authtype="CURVESERVER" + authenticator="on" +) + +template(name="host_program_topic" type="list") { + property(name="hostname") + constant(value=".") + property(name="programname") +} + +template(name="program_host_topic" type="list") { + property(name="programname") + constant(value=".") + property(name="hostname") +} + + +action( + name="to_zeromq" + type="omczmq" + socktype="PUB" + endpoints="@tcp://*:31338" + topics="host_program_topic,program_host_topic" + dynatopic="on" + topicframe="on" +) +------------------------------------------------------------------------------- diff --git a/contrib/omczmq/omczmq.c b/contrib/omczmq/omczmq.c new file mode 100644 index 0000000..a16e7e8 --- /dev/null +++ b/contrib/omczmq/omczmq.c @@ -0,0 +1,652 @@ +/* omczmq.c + * Copyright (C) 2016 Brian Knox + * Copyright (C) 2014 Rainer Gerhards + * + * Author: Brian Knox <bknox@digitalocean.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include <czmq.h> + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omczmq") + +DEF_OMOD_STATIC_DATA + +static pthread_mutex_t mutDoAct = PTHREAD_MUTEX_INITIALIZER; + +static struct cnfparamdescr modpdescr[] = { + { "authenticator", eCmdHdlrBinary, 0 }, + { "authtype", eCmdHdlrGetWord, 0 }, + { "clientcertpath", eCmdHdlrGetWord, 0 }, + { "servercertpath", eCmdHdlrGetWord, 0 } +}; + +static struct cnfparamblk modpblk = { + CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr +}; + +struct modConfData_s { + rsconf_t *pConf; + uchar *tplName; + int authenticator; + char *authType; + char *serverCertPath; + char *clientCertPath; +}; + +static modConfData_t *runModConf = NULL; +static zactor_t *authActor; + +typedef struct _instanceData { + zsock_t *sock; + bool serverish; + int sendTimeout; + zlist_t *topics; + bool sendError; + char *sockEndpoints; + int sockType; + int sendHWM; +#if(CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >=4 && ZMQ_VERSION_MINOR >=2) + int heartbeatIvl; + int heartbeatTimeout; + int heartbeatTTL; + int connectTimeout; +#endif + uchar *tplName; + sbool topicFrame; + sbool dynaTopic; +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; +} wrkrInstanceData_t; + +static struct cnfparamdescr actpdescr[] = { + { "endpoints", eCmdHdlrGetWord, 1 }, + { "socktype", eCmdHdlrGetWord, 1 }, + { "sendhwm", eCmdHdlrGetWord, 0 }, +#if(CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >=4 && ZMQ_VERSION_MINOR >=2) + { "heartbeatttl", eCmdHdlrGetWord, 0}, + { "heartbeativl", eCmdHdlrGetWord, 0}, + { "heartbeattimeout", eCmdHdlrGetWord, 0}, + { "connecttimeout", eCmdHdlrGetWord, 0}, +#endif + { "sendtimeout", eCmdHdlrGetWord, 0 }, + { "template", eCmdHdlrGetWord, 0 }, + { "topics", eCmdHdlrGetWord, 0 }, + { "topicframe", eCmdHdlrGetWord, 0}, + { "dynatopic", eCmdHdlrBinary, 0 } +}; + +static struct cnfparamblk actpblk = { + CNFPARAMBLK_VERSION, + sizeof(actpdescr) / sizeof(struct cnfparamdescr), + actpdescr +}; + +static rsRetVal initCZMQ(instanceData* pData) { + DEFiRet; + int rc; + putenv((char*)"ZSYS_SIGHANDLER=false"); + pData->sock = zsock_new(pData->sockType); + if(!pData->sock) { + LogError(0, RS_RET_NO_ERRCODE, + "omczmq: new socket failed for endpoints: %s", + pData->sockEndpoints); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + + zsock_set_sndtimeo(pData->sock, pData->sendTimeout); + +#if(CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >=4 && ZMQ_VERSION_MINOR >=2) + if(pData->heartbeatIvl > 0 && pData->heartbeatTimeout > 0 && pData->heartbeatTTL > 0) { + zsock_set_heartbeat_ivl(pData->sock, pData->heartbeatIvl); + zsock_set_heartbeat_timeout(pData->sock, pData->heartbeatTimeout); + zsock_set_heartbeat_ttl(pData->sock, pData->heartbeatTTL); + } +#endif + + if(runModConf->authType) { + if (!strcmp(runModConf->authType, "CURVESERVER")) { + zcert_t *serverCert = zcert_load(runModConf->serverCertPath); + if(!serverCert) { + LogError(0, NO_ERRCODE, "could not load cert %s", + runModConf->serverCertPath); + ABORT_FINALIZE(RS_RET_ERR); + } + zsock_set_zap_domain(pData->sock, "global"); + zsock_set_curve_server(pData->sock, 1); + zcert_apply(serverCert, pData->sock); + zcert_destroy(&serverCert); + } + else if(!strcmp(runModConf->authType, "CURVECLIENT")) { + zcert_t *serverCert = zcert_load(runModConf->serverCertPath); + if(!serverCert) { + LogError(0, NO_ERRCODE, "could not load cert %s", + runModConf->serverCertPath); + ABORT_FINALIZE(RS_RET_ERR); + } + const char *server_key = zcert_public_txt(serverCert); + zcert_destroy(&serverCert); + zsock_set_curve_serverkey(pData->sock, server_key); + + zcert_t *clientCert = zcert_load(runModConf->clientCertPath); + if(!clientCert) { + LogError(0, NO_ERRCODE, "could not load cert %s", + runModConf->clientCertPath); + ABORT_FINALIZE(RS_RET_ERR); + } + + zcert_apply(clientCert, pData->sock); + zcert_destroy(&clientCert); + } + } + + switch(pData->sockType) { + case ZMQ_PUB: +#if defined(ZMQ_RADIO) + case ZMQ_RADIO: +#endif + pData->serverish = true; + break; + case ZMQ_PUSH: +#if defined(ZMQ_SCATTER) + case ZMQ_SCATTER: +#endif + case ZMQ_DEALER: +#if defined(ZMQ_CLIENT) + case ZMQ_CLIENT: +#endif + pData->serverish = false; + break; + } + + rc = zsock_attach(pData->sock, pData->sockEndpoints, pData->serverish); + if(rc == -1) { + LogError(0, NO_ERRCODE, "zsock_attach to %s failed", + pData->sockEndpoints); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + +finalize_it: + RETiRet; +} + +static rsRetVal outputCZMQ(uchar** ppString, instanceData* pData) { + DEFiRet; + + if(NULL == pData->sock) { + CHKiRet(initCZMQ(pData)); + } + + /* if we are using a PUB (or RADIO) socket and we have a topic list then we + * need some special care and attention */ +#if defined(ZMQ_RADIO) + DBGPRINTF("omczmq: ZMQ_RADIO is defined...\n"); + if((pData->sockType == ZMQ_PUB || pData->sockType == ZMQ_RADIO) && pData->topics) { +#else + DBGPRINTF("omczmq: ZMQ_RADIO is NOT defined...\n"); + if(pData->sockType == ZMQ_PUB && pData->topics) { +#endif + int templateIndex = 1; + const char *topic = (const char *)zlist_first(pData->topics); + while(topic) { + int rc; + /* if dynaTopic is true, the topic is constructed by rsyslog + * by applying the supplied template to the message properties */ + if(pData->dynaTopic) + topic = (const char*)ppString[templateIndex]; + + if (pData->sockType == ZMQ_PUB) { + /* if topicFrame is true, send the topic as a separate zmq frame */ + if(pData->topicFrame) { + rc = zstr_sendx(pData->sock, topic, (char*)ppString[0], NULL); + } + + /* if topicFrame is false, concatenate the topic with the + * message in the same frame */ + else { + rc = zstr_sendf(pData->sock, "%s%s", topic, (char*)ppString[0]); + } + + /* if we have a send error notify rsyslog */ + if(rc != 0) { + pData->sendError = true; + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + } +#if defined(ZMQ_RADIO) + else if(pData->sockType == ZMQ_RADIO) { + DBGPRINTF("omczmq: sending on RADIO socket...\n"); + zframe_t *frame = zframe_from((char*)ppString[0]); + if (!frame) { + DBGPRINTF("omczmq: failed to create frame...\n"); + pData->sendError = true; + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + rc = zframe_set_group(frame, topic); + if (rc != 0) { + DBGPRINTF("omczmq: failed to set group '%d'...\n", rc); + pData->sendError = true; + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + DBGPRINTF("omczmq: set RADIO group to '%s'\n", topic); + rc = zframe_send(&frame, pData->sock, 0); + if(rc != 0) { + pData->sendError = true; + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + } +#endif + + /* get the next topic from the list, and increment + * our topic index */ + topic = zlist_next(pData->topics); + templateIndex++; + } + } + + /* we aren't a PUB socket and we don't have a topic list - this means + * we can just send the message using the rsyslog template */ + else { + int rc = zstr_send(pData->sock, (char*)ppString[0]); + if(rc != 0) { + pData->sendError = true; + DBGPRINTF("omczmq: send error: %d", rc); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + } +finalize_it: + RETiRet; +} + +static inline void +setInstParamDefaults(instanceData* pData) { + pData->sockEndpoints = NULL; + pData->sock = NULL; + pData->sendError = false; + pData->serverish = false; + pData->tplName = NULL; + pData->sockType = -1; + pData->sendTimeout = -1; + pData->topics = NULL; + pData->topicFrame = false; +#if(CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >=4 && ZMQ_VERSION_MINOR >=2) + pData->heartbeatIvl = 0; + pData->heartbeatTimeout = 0; + pData->heartbeatTTL = 0; +#endif +} + + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURERepeatedMsgReduction) { + iRet = RS_RET_OK; + } +ENDisCompatibleWithFeature +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +ENDdbgPrintInstInfo + +BEGINfreeInstance +CODESTARTfreeInstance + zlist_destroy(&pData->topics); + zsock_destroy(&pData->sock); + free(pData->sockEndpoints); + free(pData->tplName); +ENDfreeInstance + + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + +BEGINtryResume + instanceData *pData; +CODESTARTtryResume + pthread_mutex_lock(&mutDoAct); + pData = pWrkrData->pData; + DBGPRINTF("omczmq: trying to resume...\n"); + zsock_destroy(&pData->sock); + iRet = initCZMQ(pData); + pthread_mutex_unlock(&mutDoAct); +ENDtryResume + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + runModConf = pModConf; + runModConf->pConf = pConf; + runModConf->authenticator = 0; + runModConf->authType = NULL; + runModConf->serverCertPath = NULL; + runModConf->clientCertPath = NULL; +ENDbeginCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; + if(runModConf->authenticator == 1) { + if(!authActor) { + DBGPRINTF("omczmq: starting authActor\n"); + authActor = zactor_new(zauth, NULL); + if(!strcmp(runModConf->clientCertPath, "*")) { + zstr_sendx(authActor, "CURVE", CURVE_ALLOW_ANY, NULL); + } + else { + zstr_sendx(authActor, "CURVE", runModConf->clientCertPath, NULL); + } + zsock_wait(authActor); + } + } +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf + free(pModConf->tplName); + free(pModConf->authType); + free(pModConf->serverCertPath); + free(pModConf->clientCertPath); + DBGPRINTF("omczmq: stopping authActor\n"); + zactor_destroy(&authActor); +ENDfreeCnf + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if (pvals == NULL) { + LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + for (i=0; i<modpblk.nParams; ++i) { + if(!pvals[i].bUsed) { + DBGPRINTF("omczmq: pvals[i].bUSed continuing\n"); + continue; + } + if(!strcmp(modpblk.descr[i].name, "authenticator")) { + runModConf->authenticator = (int)pvals[i].val.d.n; + } + else if(!strcmp(modpblk.descr[i].name, "authtype")) { + runModConf->authType = es_str2cstr(pvals[i].val.d.estr, NULL); + DBGPRINTF("omczmq: authtype set to %s\n", runModConf->authType); + } + else if(!strcmp(modpblk.descr[i].name, "servercertpath")) { + runModConf->serverCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); + DBGPRINTF("omczmq: serverCertPath set to %s\n", runModConf->serverCertPath); + } + else if(!strcmp(modpblk.descr[i].name, "clientcertpath")) { + runModConf->clientCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); + DBGPRINTF("omczmq: clientCertPath set to %s\n", runModConf->clientCertPath); + } + else { + LogError(0, RS_RET_INVALID_PARAMS, + "omczmq: config error, unknown " + "param %s in setModCnf\n", + modpblk.descr[i].name); + } + } + + DBGPRINTF("omczmq: authenticator set to %d\n", runModConf->authenticator); + DBGPRINTF("omczmq: authType set to %s\n", runModConf->authType); + DBGPRINTF("omczmq: serverCertPath set to %s\n", runModConf->serverCertPath); + DBGPRINTF("omczmq: clientCertPath set to %s\n", runModConf->clientCertPath); + +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + +BEGINendCnfLoad +CODESTARTendCnfLoad + runModConf = NULL; +ENDendCnfLoad + + +BEGINdoAction + instanceData *pData; +CODESTARTdoAction + pthread_mutex_lock(&mutDoAct); + pData = pWrkrData->pData; + iRet = outputCZMQ(ppString, pData); + pthread_mutex_unlock(&mutDoAct); +ENDdoAction + + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; + int iNumTpls; +CODESTARTnewActInst + if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0; i < actpblk.nParams; ++i) { + if(!pvals[i].bUsed) { + continue; + } + + if(!strcmp(actpblk.descr[i].name, "endpoints")) { + pData->sockEndpoints = es_str2cstr(pvals[i].val.d.estr, NULL); + DBGPRINTF("omczmq: sockEndPoints set to '%s'\n", pData->sockEndpoints); + } + else if(!strcmp(actpblk.descr[i].name, "template")) { + pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + DBGPRINTF("omczmq: template set to '%s'\n", pData->tplName); + } + else if(!strcmp(actpblk.descr[i].name, "dynatopic")) { + pData->dynaTopic = pvals[i].val.d.n; + DBGPRINTF("omczmq: dynaTopic set to %s\n", pData->dynaTopic ? "true" : "false"); + } + else if(!strcmp(actpblk.descr[i].name, "sendtimeout")) { + pData->sendTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); + DBGPRINTF("omczmq: sendTimeout set to %d\n", pData->sendTimeout); + } + else if(!strcmp(actpblk.descr[i].name, "sendhwm")) { + pData->sendTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); + DBGPRINTF("omczmq: sendHWM set to %d\n", pData->sendHWM); + } +#if (CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >=4 && ZMQ_VERSION_MINOR >=2) + else if(!strcmp(actpblk.descr[i].name, "heartbeativl")) { + pData->heartbeatIvl = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); + DBGPRINTF("omczmq: heartbeatbeatIvl set to %d\n", pData->heartbeatIvl); + } + else if(!strcmp(actpblk.descr[i].name, "heartbeattimeout")) { + pData->heartbeatTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); + DBGPRINTF("omczmq: heartbeatTimeout set to %d\n", pData->heartbeatTimeout); + } + else if(!strcmp(actpblk.descr[i].name, "heartbeatttl")) { + pData->heartbeatTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); + DBGPRINTF("omczmq: heartbeatTTL set to %d\n", pData->heartbeatTTL); + } +#endif + else if(!strcmp(actpblk.descr[i].name, "socktype")){ + char *stringType = es_str2cstr(pvals[i].val.d.estr, NULL); + if(stringType != NULL){ + if(!strcmp("PUB", stringType)) { + pData->sockType = ZMQ_PUB; + DBGPRINTF("omczmq: sockType set to ZMQ_PUB\n"); + } +#if defined(ZMQ_RADIO) + else if(!strcmp("RADIO", stringType)) { + pData->sockType = ZMQ_RADIO; + DBGPRINTF("omczmq: sockType set to ZMQ_RADIO\n"); + } +#endif + else if(!strcmp("PUSH", stringType)) { + pData->sockType = ZMQ_PUSH; + DBGPRINTF("omczmq: sockType set to ZMQ_PUSH\n"); + } +#if defined(ZMQ_SCATTER) + else if(!strcmp("SCATTER", stringType)) { + pData->sockType = ZMQ_SCATTER; + DBGPRINTF("omczmq: sockType set to ZMQ_SCATTER\n"); + } +#endif + else if(!strcmp("DEALER", stringType)) { + pData->sockType = ZMQ_DEALER; + DBGPRINTF("omczmq: sockType set to ZMQ_DEALER\n"); + } +#if defined(ZMQ_CLIENT) + else if(!strcmp("CLIENT", stringType)) { + pData->sockType = ZMQ_CLIENT; + DBGPRINTF("omczmq: sockType set to ZMQ_CLIENT\n"); + } +#endif + free(stringType); + } + else{ + LogError(0, RS_RET_OUT_OF_MEMORY, + "omczmq: out of memory"); + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + } + else if(!strcmp(actpblk.descr[i].name, "topicframe")) { + pData->topicFrame = pvals[i].val.d.n; + DBGPRINTF("omczmq: topicFrame set to %s\n", pData->topicFrame ? "true" : "false"); + } + else if(!strcmp(actpblk.descr[i].name, "topics")) { + pData->topics = zlist_new(); + char *topics = es_str2cstr(pvals[i].val.d.estr, NULL); + DBGPRINTF("omczmq: topics set to %s\n", topics); + char *topics_org = topics; + char topic[256]; + if(topics == NULL){ + LogError(0, RS_RET_OUT_OF_MEMORY, + "out of memory"); + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + + while(*topics) { + char *delimiter = strchr(topics, ','); + if (!delimiter) { + delimiter = topics + strlen(topics); + } + memcpy (topic, topics, delimiter - topics); + topic[delimiter-topics] = 0; + char *current_topic = strdup(topic); + zlist_append (pData->topics, current_topic); + if(*delimiter == 0) { + break; + } + topics = delimiter + 1; + } + free(topics_org); + + } + else { + LogError(0, NO_ERRCODE, + "omczmq: config error - '%s' is not a valid option", + actpblk.descr[i].name); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + } + + iNumTpls = 1; + if (pData->dynaTopic) { + iNumTpls = zlist_size (pData->topics) + iNumTpls; + } + CODE_STD_STRING_REQUESTnewActInst(iNumTpls) + + if (pData->tplName == NULL) { + CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar*)strdup("RSYSLOG_ForwardFormat"), + OMSR_NO_RQD_TPL_OPTS)); + } + else { + CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar*)pData->tplName, OMSR_NO_RQD_TPL_OPTS)); + } + + i = 1; + if (pData->dynaTopic) { + char *topic = zlist_first(pData->topics); + while (topic) { + CHKiRet(OMSRsetEntry(*ppOMSR, i, (uchar*)strdup(topic), OMSR_NO_RQD_TPL_OPTS)); + i++; + topic = zlist_next(pData->topics); + } + } + + CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + +BEGINinitConfVars +CODESTARTinitConfVars +ENDinitConfVars + +NO_LEGACY_CONF_parseSelectorAct + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt + CODEqueryEtryPt_STD_OMOD_QUERIES + CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES + CODEqueryEtryPt_STD_CONF2_QUERIES + CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES + CODEqueryEtryPt_STD_OMOD8_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; +CODEmodInit_QueryRegCFSLineHdlr + INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); + DBGPRINTF("omczmq: module compiled with rsyslog version %s.\n", VERSION); + + INITLegCnfVars +ENDmodInit diff --git a/contrib/omfile-hardened/Makefile.am b/contrib/omfile-hardened/Makefile.am new file mode 100644 index 0000000..c1c754e --- /dev/null +++ b/contrib/omfile-hardened/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = omfile-hardened.la + +omfile_hardened_la_SOURCES = omfile-hardened.c +omfile_hardened_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +omfile_hardened_la_LDFLAGS = -module -avoid-version +omfile_hardened_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/omfile-hardened/Makefile.in b/contrib/omfile-hardened/Makefile.in new file mode 100644 index 0000000..e1ba943 --- /dev/null +++ b/contrib/omfile-hardened/Makefile.in @@ -0,0 +1,799 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omfile-hardened +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +omfile_hardened_la_DEPENDENCIES = +am_omfile_hardened_la_OBJECTS = omfile_hardened_la-omfile-hardened.lo +omfile_hardened_la_OBJECTS = $(am_omfile_hardened_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omfile_hardened_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(omfile_hardened_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omfile_hardened_la_SOURCES) +DIST_SOURCES = $(omfile_hardened_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omfile-hardened.la +omfile_hardened_la_SOURCES = omfile-hardened.c +omfile_hardened_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +omfile_hardened_la_LDFLAGS = -module -avoid-version +omfile_hardened_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omfile-hardened/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omfile-hardened/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omfile-hardened.la: $(omfile_hardened_la_OBJECTS) $(omfile_hardened_la_DEPENDENCIES) $(EXTRA_omfile_hardened_la_DEPENDENCIES) + $(AM_V_CCLD)$(omfile_hardened_la_LINK) -rpath $(pkglibdir) $(omfile_hardened_la_OBJECTS) $(omfile_hardened_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omfile_hardened_la-omfile-hardened.lo: omfile-hardened.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omfile_hardened_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omfile_hardened_la-omfile-hardened.lo -MD -MP -MF $(DEPDIR)/omfile_hardened_la-omfile-hardened.Tpo -c -o omfile_hardened_la-omfile-hardened.lo `test -f 'omfile-hardened.c' || echo '$(srcdir)/'`omfile-hardened.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omfile_hardened_la-omfile-hardened.Tpo $(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omfile-hardened.c' object='omfile_hardened_la-omfile-hardened.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omfile_hardened_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omfile_hardened_la-omfile-hardened.lo `test -f 'omfile-hardened.c' || echo '$(srcdir)/'`omfile-hardened.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omfile-hardened/omfile-hardened.c b/contrib/omfile-hardened/omfile-hardened.c new file mode 100644 index 0000000..2b14a2c --- /dev/null +++ b/contrib/omfile-hardened/omfile-hardened.c @@ -0,0 +1,1654 @@ +/* omfile.c + * This is the implementation of the build-in file output module. + * + * NOTE: read comments in module-template.h to understand how this file + * works! + * + * File begun on 2007-07-21 by RGerhards (extracted from syslogd.c, which + * at the time of the fork from sysklogd was under BSD license) + * + * A large re-write of this file was done in June, 2009. The focus was + * to introduce many more features (like zipped writing), clean up the code + * and make it more reliable. In short, that rewrite tries to provide a new + * solid basis for the next three to five years to come. During it, bugs + * may have been introduced ;) -- rgerhards, 2009-06-04 + * + * Note that as of 2010-02-28 this module does no longer handle + * pipes. These have been moved to ompipe, to reduced the entanglement + * between the two different functionalities. -- rgerhards + * + * Copyright 2007-2017 Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include "glbl.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <assert.h> +#include <errno.h> +#include <ctype.h> +#include <libgen.h> +#include <unistd.h> +#include <sys/file.h> +#include <fcntl.h> +#include <sys/statvfs.h> +#ifdef HAVE_ATOMIC_BUILTINS +# include <pthread.h> +#endif + + +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "outchannel.h" +#include "omfile.h" +#include "cfsysline.h" +#include "module-template.h" +#include "errmsg.h" +#include "stream.h" +#include "unicode-helper.h" +#include "atomic.h" +#include "statsobj.h" +#include "sigprov.h" +#include "cryprov.h" +#include "parserif.h" +#include "janitor.h" +#include "rsconf.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omfile") + +/* forward definitions */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal); + +/* internal structures + */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(strm) +DEFobjCurrIf(statsobj) + +/* for our current LRU mechanism, we need a monotonically increasing counters. We use + * it much like a "Lamport logical clock": we do not need the actual time, we just need + * to know the sequence in which files were accessed. So we use a simple counter to + * create that sequence. We use an unsigned 64 bit value which is extremely unlike to + * wrap within the lifetime of a process. If we process 1,000,000 file writes per + * second, the process could still exist over 500,000 years before a wrap to 0 happens. + * That should be sufficient (and even than, there would no really bad effect ;)). + * The variable below is the global counter/clock. + */ +#if HAVE_ATOMIC_BUILTINS64 +static uint64 clockFileAccess = 0; +#else +static unsigned clockFileAccess = 0; +#endif +/* and the "tick" function */ +#ifndef HAVE_ATOMIC_BUILTINS +static pthread_mutex_t mutClock; +#endif +static uint64 +getClockFileAccess(void) +{ +#if HAVE_ATOMIC_BUILTINS64 + return ATOMIC_INC_AND_FETCH_uint64(&clockFileAccess, &mutClock); +#else + return ATOMIC_INC_AND_FETCH_unsigned(&clockFileAccess, &mutClock); +#endif +} + + +/* The following structure is a dynafile name cache entry. + */ +struct s_dynaFileCacheEntry { + uchar *pName; /* name currently open, if dynamic name */ + strm_t *pStrm; /* our output stream */ + void *sigprovFileData; /* opaque data ptr for provider use */ + uint64 clkTickAccessed;/* for LRU - based on clockFileAccess */ + short nInactive; /* number of minutes not writen - for close timeout */ +}; +typedef struct s_dynaFileCacheEntry dynaFileCacheEntry; + + +#define IOBUF_DFLT_SIZE 4096 /* default size for io buffers */ +#define FLUSH_INTRVL_DFLT 1 /* default buffer flush interval (in seconds) */ +#define USE_ASYNCWRITER_DFLT 0 /* default buffer use async writer */ +#define FLUSHONTX_DFLT 1 /* default for flush on TX end */ + +typedef struct _instanceData { + pthread_mutex_t mutWrite; /* guard against multiple instances writing to single file */ + uchar *fname; /* file or template name (display only) */ + uchar *tplName; /* name of assigned template */ + strm_t *pStrm; /* our output stream */ + short nInactive; /* number of minutes not writen (STATIC files only) */ + char bDynamicName; /* 0 - static name, 1 - dynamic name (with properties) */ + int fCreateMode; /* file creation mode for open() */ + int fDirCreateMode; /* creation mode for mkdir() */ + int bCreateDirs; /* auto-create directories? */ + int bSyncFile; /* should the file by sync()'ed? 1- yes, 0- no */ + uint8_t iNumTpls; /* number of tpls we use */ + uid_t fileUID; /* IDs for creation */ + uid_t dirUID; + gid_t fileGID; + gid_t dirGID; + int bFailOnChown; /* fail creation if chown fails? */ + uchar *sigprovName; /* signature provider */ + uchar *sigprovNameFull;/* full internal signature provider name */ + sigprov_if_t sigprov; /* ptr to signature provider interface */ + void *sigprovData; /* opaque data ptr for provider use */ + void *sigprovFileData;/* opaque data ptr for file instance */ + sbool useSigprov; /* quicker than checkig ptr (1 vs 8 bytes!) */ + uchar *cryprovName; /* crypto provider */ + uchar *cryprovNameFull;/* full internal crypto provider name */ + void *cryprovData; /* opaque data ptr for provider use */ + cryprov_if_t cryprov; /* ptr to crypto provider interface */ + sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */ + int iCurrElt; /* currently active cache element (-1 = none) */ + uint iCurrCacheSize; /* currently cache size (1-based) */ + uint iDynaFileCacheSize; /* size of file handle cache */ + /* The cache is implemented as an array. An empty element is indicated + * by a NULL pointer. Memory is allocated as needed. The following + * pointer points to the overall structure. + */ + dynaFileCacheEntry **dynCache; + off_t iSizeLimit; /* file size limit, 0 = no limit */ + uchar *pszSizeLimitCmd; /* command to carry out when size limit is reached */ + int iZipLevel; /* zip mode to use for this selector */ + uint iIOBufSize; /* size of associated io buffer */ + int iFlushInterval; /* how fast flush buffer on inactivity? */ + short iCloseTimeout; /* after how many *minutes* shall the file be closed if inactive? */ + sbool bFlushOnTXEnd; /* flush write buffers when transaction has ended? */ + sbool bUseAsyncWriter; /* use async stream writer? */ + sbool bVeryRobustZip; + statsobj_t *stats; /* dynafile, primarily cache stats */ + STATSCOUNTER_DEF(ctrRequests, mutCtrRequests); + STATSCOUNTER_DEF(ctrLevel0, mutCtrLevel0); + STATSCOUNTER_DEF(ctrEvict, mutCtrEvict); + STATSCOUNTER_DEF(ctrMiss, mutCtrMiss); + STATSCOUNTER_DEF(ctrMax, mutCtrMax); + STATSCOUNTER_DEF(ctrCloseTimeouts, mutCtrCloseTimeouts); + char janitorID[128]; /* holds ID for janitor calls */ +} instanceData; + + +typedef struct wrkrInstanceData { + instanceData *pData; +} wrkrInstanceData_t; + + +typedef struct configSettings_s { + uint iDynaFileCacheSize; /* max cache for dynamic files */ + int fCreateMode; /* mode to use when creating files */ + int fDirCreateMode; /* mode to use when creating files */ + int bFailOnChown; /* fail if chown fails? */ + uid_t fileUID; /* UID to be used for newly created files */ + uid_t fileGID; /* GID to be used for newly created files */ + uid_t dirUID; /* UID to be used for newly created directories */ + uid_t dirGID; /* GID to be used for newly created directories */ + int bCreateDirs;/* auto-create directories for dynaFiles: 0 - no, 1 - yes */ + int bEnableSync;/* enable syncing of files (no dash in front of pathname in conf): 0 - no, 1 - yes */ + int iZipLevel; /* zip compression mode (0..9 as usual) */ + sbool bFlushOnTXEnd;/* flush write buffers when transaction has ended? */ + int64 iIOBufSize; /* size of an io buffer */ + int iFlushInterval; /* how often flush the output buffer on inactivity? */ + int bUseAsyncWriter; /* should we enable asynchronous writing? */ + EMPTY_STRUCT +} configSettings_t; +static configSettings_t cs; +uchar *pszFileDfltTplName; /* name of the default template to use */ + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + uchar *tplName; /* default template */ + int fCreateMode; /* default mode to use when creating files */ + int fDirCreateMode; /* default mode to use when creating files */ + uid_t fileUID; /* default IDs for creation */ + uid_t dirUID; + gid_t fileGID; + gid_t dirGID; + int bDynafileDoNotSuspend; +}; + +static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ +static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current exec process */ + +/* tables for interfacing with the v6 config system */ +/* module-global parameters */ +static struct cnfparamdescr modpdescr[] = { + { "template", eCmdHdlrGetWord, 0 }, + { "dircreatemode", eCmdHdlrFileCreateMode, 0 }, + { "filecreatemode", eCmdHdlrFileCreateMode, 0 }, + { "dirowner", eCmdHdlrUID, 0 }, + { "dirownernum", eCmdHdlrInt, 0 }, + { "dirgroup", eCmdHdlrGID, 0 }, + { "dirgroupnum", eCmdHdlrInt, 0 }, + { "fileowner", eCmdHdlrUID, 0 }, + { "fileownernum", eCmdHdlrInt, 0 }, + { "filegroup", eCmdHdlrGID, 0 }, + { "dynafile.donotsuspend", eCmdHdlrBinary, 0 }, + { "filegroupnum", eCmdHdlrInt, 0 }, +}; +static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, + sizeof(modpdescr)/sizeof(struct cnfparamdescr), + modpdescr + }; + +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "dynafilecachesize", eCmdHdlrInt, 0 }, /* legacy: dynafilecachesize */ + { "ziplevel", eCmdHdlrInt, 0 }, /* legacy: omfileziplevel */ + { "flushinterval", eCmdHdlrInt, 0 }, /* legacy: omfileflushinterval */ + { "asyncwriting", eCmdHdlrBinary, 0 }, /* legacy: omfileasyncwriting */ + { "veryrobustzip", eCmdHdlrBinary, 0 }, + { "flushontxend", eCmdHdlrBinary, 0 }, /* legacy: omfileflushontxend */ + { "iobuffersize", eCmdHdlrSize, 0 }, /* legacy: omfileiobuffersize */ + { "dirowner", eCmdHdlrUID, 0 }, /* legacy: dirowner */ + { "dirownernum", eCmdHdlrInt, 0 }, /* legacy: dirownernum */ + { "dirgroup", eCmdHdlrGID, 0 }, /* legacy: dirgroup */ + { "dirgroupnum", eCmdHdlrInt, 0 }, /* legacy: dirgroupnum */ + { "fileowner", eCmdHdlrUID, 0 }, /* legacy: fileowner */ + { "fileownernum", eCmdHdlrInt, 0 }, /* legacy: fileownernum */ + { "filegroup", eCmdHdlrGID, 0 }, /* legacy: filegroup */ + { "filegroupnum", eCmdHdlrInt, 0 }, /* legacy: filegroupnum */ + { "dircreatemode", eCmdHdlrFileCreateMode, 0 }, /* legacy: dircreatemode */ + { "filecreatemode", eCmdHdlrFileCreateMode, 0 }, /* legacy: filecreatemode */ + { "failonchownfailure", eCmdHdlrBinary, 0 }, /* legacy: failonchownfailure */ + { "createdirs", eCmdHdlrBinary, 0 }, /* legacy: createdirs */ + { "sync", eCmdHdlrBinary, 0 }, /* legacy: actionfileenablesync */ + { "file", eCmdHdlrString, 0 }, /* either "file" or ... */ + { "dynafile", eCmdHdlrString, 0 }, /* "dynafile" MUST be present */ + { "sig.provider", eCmdHdlrGetWord, 0 }, + { "cry.provider", eCmdHdlrGetWord, 0 }, + { "closetimeout", eCmdHdlrPositiveInt, 0 }, + { "template", eCmdHdlrGetWord, 0 } +}; +static struct cnfparamblk actpblk = + { CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr + }; + + +/* this function gets the default template. It coordinates action between + * old-style and new-style configuration parts. + */ +static uchar* +getDfltTpl(void) +{ + if(loadModConf != NULL && loadModConf->tplName != NULL) + return loadModConf->tplName; + else if(pszFileDfltTplName == NULL) + return (uchar*)"RSYSLOG_FileFormat"; + else + return pszFileDfltTplName; +} + + +BEGINinitConfVars /* (re)set config variables to default values */ +CODESTARTinitConfVars + pszFileDfltTplName = NULL; /* make sure this can be free'ed! */ + iRet = resetConfigVariables(NULL, NULL); /* params are dummies */ +ENDinitConfVars + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURERepeatedMsgReduction) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + if(pData->bDynamicName) { + dbgprintf("[dynamic]\n"); + } else { /* regular file */ + dbgprintf("%s%s\n", pData->fname, + (pData->pStrm == NULL) ? " (closed)" : ""); + } + + dbgprintf("\ttemplate='%s'\n", pData->fname); + dbgprintf("\tuse async writer=%d\n", pData->bUseAsyncWriter); + dbgprintf("\tflush on TX end=%d\n", pData->bFlushOnTXEnd); + dbgprintf("\tflush interval=%d\n", pData->iFlushInterval); + dbgprintf("\tfile cache size=%d\n", pData->iDynaFileCacheSize); + dbgprintf("\tcreate directories: %s\n", pData->bCreateDirs ? "on" : "off"); + dbgprintf("\tvery robust zip: %s\n", pData->bCreateDirs ? "on" : "off"); + dbgprintf("\tfile owner %d, group %d\n", (int) pData->fileUID, (int) pData->fileGID); + dbgprintf("\tdirectory owner %d, group %d\n", (int) pData->dirUID, (int) pData->dirGID); + dbgprintf("\tdir create mode 0%3.3o, file create mode 0%3.3o\n", + pData->fDirCreateMode, pData->fCreateMode); + dbgprintf("\tfail if owner/group can not be set: %s\n", pData->bFailOnChown ? "yes" : "no"); +ENDdbgPrintInstInfo + + + +/* set the default template to be used + * This is a module-global parameter, and as such needs special handling. It needs to + * be coordinated with values set via the v2 config system (rsyslog v6+). What we do + * is we do not permit this directive after the v2 config system has been used to set + * the parameter. + */ +static rsRetVal +setLegacyDfltTpl(void __attribute__((unused)) *pVal, uchar* newVal) +{ + DEFiRet; + + if(loadModConf != NULL && loadModConf->tplName != NULL) { + free(newVal); + parser_errmsg("omfile: default template already set via module " + "global parameter - can no longer be changed"); + ABORT_FINALIZE(RS_RET_ERR); + } + free(pszFileDfltTplName); + pszFileDfltTplName = newVal; +finalize_it: + RETiRet; +} + + +/* set the dynaFile cache size. Does some limit checking. + * rgerhards, 2007-07-31 + */ +static rsRetVal setDynaFileCacheSize(void __attribute__((unused)) *pVal, int iNewVal) +{ + DEFiRet; + + if(iNewVal < 1) { + errno = 0; + parser_errmsg( + "DynaFileCacheSize must be greater 0 (%d given), changed to 1.", iNewVal); + iRet = RS_RET_VAL_OUT_OF_RANGE; + iNewVal = 1; + } else if(iNewVal > 1000) { + errno = 0; + parser_errmsg( + "DynaFileCacheSize maximum is 1,000 (%d given), changed to 1,000.", iNewVal); + iRet = RS_RET_VAL_OUT_OF_RANGE; + iNewVal = 1000; + } + + cs.iDynaFileCacheSize = iNewVal; + DBGPRINTF("DynaFileCacheSize changed to %d.\n", iNewVal); + + RETiRet; +} + + +/* Helper to cfline(). Parses a output channel name up until the first + * comma and then looks for the template specifier. Tries + * to find that template. Maps the output channel to the + * proper filed structure settings. Everything is stored in the + * filed struct. Over time, the dependency on filed might be + * removed. + * rgerhards 2005-06-21 + */ +static rsRetVal cflineParseOutchannel(instanceData *pData, uchar* p, omodStringRequest_t *pOMSR, + int iEntry, int iTplOpts) +{ + DEFiRet; + size_t i; + struct outchannel *pOch; + char szBuf[128]; /* should be more than sufficient */ + + ++p; /* skip '$' */ + i = 0; + /* get outchannel name */ + while(*p && *p != ';' && *p != ' ' && + i < (sizeof(szBuf) - 1) ) { + szBuf[i++] = *p++; + } + szBuf[i] = '\0'; + + /* got the name, now look up the channel... */ + pOch = ochFind(szBuf, i); + + if(pOch == NULL) { + parser_errmsg( + "outchannel '%s' not found - ignoring action line", + szBuf); + ABORT_FINALIZE(RS_RET_NOT_FOUND); + } + + /* check if there is a file name in the outchannel... */ + if(pOch->pszFileTemplate == NULL) { + parser_errmsg( + "outchannel '%s' has no file name template - ignoring action line", + szBuf); + ABORT_FINALIZE(RS_RET_ERR); + } + + /* OK, we finally got a correct template. So let's use it... */ + pData->fname = ustrdup(pOch->pszFileTemplate); + pData->iSizeLimit = pOch->uSizeLimit; + /* WARNING: It is dangerous "just" to pass the pointer. As we + * never rebuild the output channel description, this is acceptable here. + */ + pData->pszSizeLimitCmd = pOch->cmdOnSizeLimit; + + iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts, getDfltTpl()); + +finalize_it: + RETiRet; +} + + +/* This function deletes an entry from the dynamic file name + * cache. A pointer to the cache must be passed in as well + * as the index of the to-be-deleted entry. This index may + * point to an unallocated entry, in whcih case the + * function immediately returns. Parameter bFreeEntry is 1 + * if the entry should be free()ed and 0 if not. + */ +static rsRetVal +dynaFileDelCacheEntry(instanceData *__restrict__ const pData, const int iEntry, const int bFreeEntry) +{ + dynaFileCacheEntry **pCache = pData->dynCache; + DEFiRet; + assert(pCache != NULL); + + if(pCache[iEntry] == NULL) + FINALIZE; + + DBGPRINTF("Removing entry %d for file '%s' from dynaCache.\n", iEntry, + pCache[iEntry]->pName == NULL ? UCHAR_CONSTANT("[OPEN FAILED]") : pCache[iEntry]->pName); + + if(pCache[iEntry]->pName != NULL) { + free(pCache[iEntry]->pName); + pCache[iEntry]->pName = NULL; + } + + if(pCache[iEntry]->pStrm != NULL) { + strm.Destruct(&pCache[iEntry]->pStrm); + if(pData->useSigprov) { + pData->sigprov.OnFileClose(pCache[iEntry]->sigprovFileData); + pCache[iEntry]->sigprovFileData = NULL; + } + } + + if(bFreeEntry) { + free(pCache[iEntry]); + pCache[iEntry] = NULL; + } + +finalize_it: + RETiRet; +} + + +/* This function frees all dynamic file name cache entries and closes the + * relevant files. Part of Shutdown and HUP processing. + * rgerhards, 2008-10-23 + */ +static void +dynaFileFreeCacheEntries(instanceData *__restrict__ const pData) +{ + register uint i; + assert(pData != NULL); + + for(i = 0 ; i < pData->iCurrCacheSize ; ++i) { + dynaFileDelCacheEntry(pData, i, 1); + } + pData->iCurrElt = -1; /* invalidate current element */ +} + + +/* This function frees the dynamic file name cache. + */ +static void dynaFileFreeCache(instanceData *__restrict__ const pData) +{ + assert(pData != NULL); + + dynaFileFreeCacheEntries(pData); + if(pData->dynCache != NULL) + free(pData->dynCache); +} + + +/* close current file */ +static rsRetVal +closeFile(instanceData *__restrict__ const pData) +{ + DEFiRet; + if(pData->useSigprov) { + pData->sigprov.OnFileClose(pData->sigprovFileData); + pData->sigprovFileData = NULL; + } + strm.Destruct(&pData->pStrm); + RETiRet; +} + + +/* This prepares the signature provider to process a file */ +static rsRetVal +sigprovPrepare(instanceData *__restrict__ const pData, uchar *__restrict__ const fn) +{ + DEFiRet; + pData->sigprov.OnFileOpen(pData->sigprovData, fn, &pData->sigprovFileData); + RETiRet; +} + +/* This is now shared code for all types of files. It simply prepares + * file access, which, among others, means the the file wil be opened + * and any directories in between will be created (based on config, of + * course). -- rgerhards, 2008-10-22 + * changed to iRet interface - 2009-03-19 + */ +static rsRetVal +prepareFile(instanceData *__restrict__ const pData, const uchar *__restrict__ const newFileName) +{ + int fd; + char errStr[1024]; /* buffer for strerr() */ + DEFiRet; + + pData->pStrm = NULL; + if(access((char*)newFileName, F_OK) != 0) { + /* file does not exist, create it (and eventually parent directories */ + if(pData->bCreateDirs) { + /* We first need to create parent dirs if they are missing. + * We do not report any errors here ourselfs but let the code + * fall through to error handler below. + */ + if(makeFileParentDirs(newFileName, ustrlen(newFileName), + pData->fDirCreateMode, pData->dirUID, + pData->dirGID, pData->bFailOnChown) != 0) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + parser_errmsg( "omfile: creating parent " + "directories for file '%s' failed: %s", + newFileName, errStr); + ABORT_FINALIZE(RS_RET_ERR); /* we give up */ + } + } + /* no matter if we needed to create directories or not, we now try to create + * the file. -- rgerhards, 2008-12-18 (based on patch from William Tisater) + */ + fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_CLOEXEC, + pData->fCreateMode); + if(fd != -1) { + /* check and set uid/gid */ + if(pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) { + /* we need to set owner/group */ + if(fchown(fd, pData->fileUID, pData->fileGID) != 0) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + parser_errmsg( + "omfile: chown for file '%s' failed: %s", + newFileName, errStr); + if(pData->bFailOnChown) { + close(fd); + ABORT_FINALIZE(RS_RET_ERR); /* we give up */ + } + /* we will silently ignore the chown() failure + * if configured to do so. + */ + } + } + close(fd); /* close again, as we need a stream further on */ + } + else { + ABORT_FINALIZE(RS_RET_ERR); + } + } + + /* the copies below are clumpsy, but there is no way around given the + * anomalies in dirname() and basename() [they MODIFY the provided buffer...] + */ + uchar szNameBuf[MAXFNAME+1]; + uchar szDirName[MAXFNAME+1]; + uchar szBaseName[MAXFNAME+1]; + ustrncpy(szNameBuf, newFileName, MAXFNAME); + szNameBuf[MAXFNAME] = '\0'; + ustrncpy(szDirName, (uchar*)dirname((char*)szNameBuf), MAXFNAME); + szDirName[MAXFNAME] = '\0'; + ustrncpy(szNameBuf, newFileName, MAXFNAME); + szNameBuf[MAXFNAME] = '\0'; + ustrncpy(szBaseName, (uchar*)basename((char*)szNameBuf), MAXFNAME); + szBaseName[MAXFNAME] = '\0'; + + CHKiRet(strm.Construct(&pData->pStrm)); + CHKiRet(strm.SetFName(pData->pStrm, szBaseName, ustrlen(szBaseName))); + CHKiRet(strm.SetDir(pData->pStrm, szDirName, ustrlen(szDirName))); + CHKiRet(strm.SetiZipLevel(pData->pStrm, pData->iZipLevel)); + CHKiRet(strm.SetbVeryReliableZip(pData->pStrm, pData->bVeryRobustZip)); + CHKiRet(strm.SetsIOBufSize(pData->pStrm, (size_t) pData->iIOBufSize)); + CHKiRet(strm.SettOperationsMode(pData->pStrm, STREAMMODE_WRITE_APPEND)); + CHKiRet(strm.SettOpenMode(pData->pStrm, cs.fCreateMode)); + CHKiRet(strm.SetbSync(pData->pStrm, pData->bSyncFile)); + CHKiRet(strm.SetsType(pData->pStrm, STREAMTYPE_FILE_SINGLE)); + CHKiRet(strm.SetiSizeLimit(pData->pStrm, pData->iSizeLimit)); + if(pData->useCryprov) { + CHKiRet(strm.Setcryprov(pData->pStrm, &pData->cryprov)); + CHKiRet(strm.SetcryprovData(pData->pStrm, pData->cryprovData)); + } + /* set the flush interval only if we actually use it - otherwise it will activate + * async processing, which is a real performance waste if we do not do buffered + * writes! -- rgerhards, 2009-07-06 + */ + if(pData->bUseAsyncWriter) + CHKiRet(strm.SetiFlushInterval(pData->pStrm, pData->iFlushInterval)); + if(pData->pszSizeLimitCmd != NULL) + CHKiRet(strm.SetpszSizeLimitCmd(pData->pStrm, ustrdup(pData->pszSizeLimitCmd))); + CHKiRet(strm.ConstructFinalize(pData->pStrm)); + + if(pData->useSigprov) + sigprovPrepare(pData, szNameBuf); + +finalize_it: + if(iRet != RS_RET_OK) { + if(pData->pStrm != NULL) { + closeFile(pData); + } + } + RETiRet; +} + +// <kortemik date="2018-02-20"> +/* verify enough we have space left for writes */ +static rsRetVal +fsCheck(instanceData *__restrict__ const pData, const uchar *__restrict__ const fileName) +{ + DEFiRet; + struct statvfs stat; + char *pathcopy; + const char *path; + + pathcopy = strdup((char*)fileName); + path = dirname(pathcopy); + + if (statvfs(path, &stat) != 0) { + iRet = RS_RET_FILE_NO_STAT; + LogError(0, iRet, "could not stat %s", path); + FINALIZE; + } + + /* check if we have space available for all buffers to be flushed and for + * a maximum length message, perhaps current msg size would be enough */ + if (stat.f_bsize * stat.f_bavail < + pData->iIOBufSize * pData->iDynaFileCacheSize + (uint)(glbl.GetMaxLine(runModConf->pConf))) + { + iRet = RS_RET_FS_ERR; + LogError(0, iRet, "too few available blocks in %s", path); + FINALIZE; + } + /* there must be enough inodes left, one is left for administrative purposes + * check is not done if file system reports 0 total inodes, such as btrfs */ + if (stat.f_favail < 2 && stat.f_files > 0) + { + iRet = RS_RET_FS_ERR; + LogError(0, iRet, "too few available inodes in %s", path); + FINALIZE; + } + + /* file system must not be read only */ + if (stat.f_flag == ST_RDONLY) + { + iRet = RS_RET_FS_ERR; + LogError(0, iRet, "file-system is read-only in %s", path); + FINALIZE; + } + + iRet = RS_RET_OK; + +finalize_it: + if (pathcopy != NULL) + free(pathcopy); + RETiRet; +} +// </kortemik> + +/* This function handles dynamic file names. It checks if the + * requested file name is already open and, if not, does everything + * needed to switch to the it. + * Function returns 0 if all went well and non-zero otherwise. + * On successful return pData->fd must point to the correct file to + * be written. + * This is a helper to writeFile(). rgerhards, 2007-07-03 + */ +static rsRetVal +prepareDynFile(instanceData *__restrict__ const pData, const uchar *__restrict__ const newFileName) +{ + uint64 ctOldest; /* "timestamp" of oldest element */ + int iOldest; + uint i; + int iFirstFree; + rsRetVal localRet; + dynaFileCacheEntry **pCache; + DEFiRet; + + assert(pData != NULL); + assert(newFileName != NULL); + + pCache = pData->dynCache; + + /* first check, if we still have the current file */ + if( (pData->iCurrElt != -1) + && !ustrcmp(newFileName, pCache[pData->iCurrElt]->pName)) { + CHKiRet(fsCheck(pData, newFileName)); + + /* great, we are all set */ + pCache[pData->iCurrElt]->clkTickAccessed = getClockFileAccess(); + STATSCOUNTER_INC(pData->ctrLevel0, pData->mutCtrLevel0); + /* LRU needs only a strictly monotonically increasing counter, so such a one could do */ + FINALIZE; + } + + /* ok, no luck. Now let's search the table if we find a matching spot. + * While doing so, we also prepare for creation of a new one. + */ + pData->iCurrElt = -1; /* invalid current element pointer */ + iFirstFree = -1; /* not yet found */ + iOldest = 0; /* we assume the first element to be the oldest - that will change as we loop */ + ctOldest = getClockFileAccess(); /* there must always be an older one */ + for(i = 0 ; i < pData->iCurrCacheSize ; ++i) { + if(pCache[i] == NULL || pCache[i]->pName == NULL) { + if(iFirstFree == -1) + iFirstFree = i; + } else { /* got an element, let's see if it matches */ + if(!ustrcmp(newFileName, pCache[i]->pName)) { + CHKiRet(fsCheck(pData, newFileName)); + + /* we found our element! */ + pData->pStrm = pCache[i]->pStrm; + if(pData->useSigprov) + pData->sigprovFileData = pCache[i]->sigprovFileData; + pData->iCurrElt = i; + pCache[i]->clkTickAccessed = getClockFileAccess(); /* update "timestamp" for LRU */ + FINALIZE; + } + /* did not find it - so lets keep track of the counters for LRU */ + if(pCache[i]->clkTickAccessed < ctOldest) { + ctOldest = pCache[i]->clkTickAccessed; + iOldest = i; + } + } + } + + /* we have not found an entry */ + STATSCOUNTER_INC(pData->ctrMiss, pData->mutCtrMiss); + + /* similarly, we need to set the current pStrm to NULL, because otherwise, if prepareFile() fails, + * we may end up using an old stream. This bug depends on how exactly prepareFile fails, + * but it could be triggered in the common case of a failed open() system call. + * rgerhards, 2010-03-22 + */ + pData->pStrm = NULL, pData->sigprovFileData = NULL; + + if(iFirstFree == -1 && (pData->iCurrCacheSize < pData->iDynaFileCacheSize)) { + /* there is space left, so set it to that index */ + iFirstFree = pData->iCurrCacheSize++; + STATSCOUNTER_SETMAX_NOMUT(pData->ctrMax, (unsigned) pData->iCurrCacheSize); + } + + /* Note that the following code sequence does not work with the cache entry itself, + * but rather with pData->pStrm, the (sole) stream pointer in the non-dynafile case. + * The cache array is only updated after the open was successful. -- rgerhards, 2010-03-21 + */ + if(iFirstFree == -1) { + dynaFileDelCacheEntry(pData, iOldest, 0); + STATSCOUNTER_INC(pData->ctrEvict, pData->mutCtrEvict); + iFirstFree = iOldest; /* this one *is* now free ;) */ + } else { + /* we need to allocate memory for the cache structure */ + CHKmalloc(pCache[iFirstFree] = (dynaFileCacheEntry*) calloc(1, sizeof(dynaFileCacheEntry))); + } + + /* Ok, we finally can open the file */ + localRet = prepareFile(pData, newFileName); /* ignore exact error, we check fd below */ + + /* check if we had an error */ + if(localRet != RS_RET_OK) { + /* We do no longer care about internal messages. The errmsg rate limiter + * will take care of too-frequent error messages. + */ + parser_errmsg("Could not open dynamic file '%s' [state %d]", newFileName, localRet); + ABORT_FINALIZE(localRet); + } + + localRet = fsCheck(pData, newFileName); + if(localRet != RS_RET_OK) { + parser_errmsg("Invalid file-system condition for dynamic file '%s' [state %d]", newFileName, localRet); + ABORT_FINALIZE(localRet); + } + + if((pCache[iFirstFree]->pName = ustrdup(newFileName)) == NULL) { + closeFile(pData); /* need to free failed entry! */ + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + } + pCache[iFirstFree]->pStrm = pData->pStrm; + if(pData->useSigprov) + pCache[iFirstFree]->sigprovFileData = pData->sigprovFileData; + pCache[iFirstFree]->clkTickAccessed = getClockFileAccess(); + pData->iCurrElt = iFirstFree; + DBGPRINTF("Added new entry %d for file cache, file '%s'.\n", iFirstFree, newFileName); + +finalize_it: + if(iRet == RS_RET_OK) + pCache[pData->iCurrElt]->nInactive = 0; + RETiRet; +} + + +/* do the actual write process. This function is to be called once we are ready for writing. + * It will do buffered writes and persist data only when the buffer is full. Note that we must + * be careful to detect when the file handle changed. + * rgerhards, 2009-06-03 + */ +static rsRetVal +doWrite(instanceData *__restrict__ const pData, uchar *__restrict__ const pszBuf, const int lenBuf) +{ + DEFiRet; + assert(pData != NULL); + assert(pszBuf != NULL); + + DBGPRINTF("omfile: write to stream, pData->pStrm %p, lenBuf %d, strt data %.128s\n", + pData->pStrm, lenBuf, pszBuf); + if(pData->pStrm != NULL){ + CHKiRet(strm.Write(pData->pStrm, pszBuf, lenBuf)); + if(pData->useSigprov) { + CHKiRet(pData->sigprov.OnRecordWrite(pData->sigprovFileData, pszBuf, lenBuf)); + } + } + +finalize_it: + RETiRet; +} + +/* rgerhards 2004-11-11: write to a file output. */ +static rsRetVal +writeFile(instanceData *__restrict__ const pData, + const actWrkrIParams_t *__restrict__ const pParam, + const int iMsg) +{ + DEFiRet; + + STATSCOUNTER_INC(pData->ctrRequests, pData->mutCtrRequests); + /* first check if we have a dynamic file name and, if so, + * check if it still is ok or a new file needs to be created + */ + if(pData->bDynamicName) { + DBGPRINTF("omfile: file to log to: %s\n", + actParam(pParam, pData->iNumTpls, iMsg, 1).param); + CHKiRet(prepareDynFile(pData, actParam(pParam, pData->iNumTpls, iMsg, 1).param)); + } else { /* "regular", non-dynafile */ + if(pData->pStrm == NULL) { + CHKiRet(prepareFile(pData, pData->fname)); + if(pData->pStrm == NULL) { + parser_errmsg( + "Could not open output file '%s'", pData->fname); + } + CHKiRet(fsCheck(pData, pData->fname)); + } + pData->nInactive = 0; + } + + iRet = doWrite(pData, actParam(pParam, pData->iNumTpls, iMsg, 0).param, + actParam(pParam, pData->iNumTpls, iMsg, 0).lenStr); + +finalize_it: + RETiRet; +} + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; + pModConf->tplName = NULL; + pModConf->fCreateMode = 0644; + pModConf->fDirCreateMode = 0700; + pModConf->fileUID = -1; + pModConf->dirUID = -1; + pModConf->fileGID = -1; + pModConf->dirGID = -1; + pModConf->bDynafileDoNotSuspend = 1; +ENDbeginCnfLoad + +BEGINsetModCnf + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTsetModCnf + pvals = nvlstGetParams(lst, &modpblk, NULL); + if(pvals == NULL) { + parser_errmsg("error processing module " + "config parameters [module(...)]"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("module (global) param blk for omfile:\n"); + cnfparamsPrint(&modpblk, pvals); + } + + for(i = 0 ; i < modpblk.nParams ; ++i) { + if(!pvals[i].bUsed) { + continue; + } + + if(!strcmp(modpblk.descr[i].name, "template")) { + loadModConf->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + if(pszFileDfltTplName != NULL) { + parser_errmsg("omfile: warning: default template was already " + "set via legacy directive - may lead to inconsistent " + "results."); + } + } else if(!strcmp(modpblk.descr[i].name, "dircreatemode")) { + loadModConf->fDirCreateMode = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "filecreatemode")) { + loadModConf->fCreateMode = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "dirowner")) { + loadModConf->dirUID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "dirownernum")) { + loadModConf->dirUID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "dirgroup")) { + loadModConf->dirGID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "dirgroupnum")) { + loadModConf->dirGID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "fileowner")) { + loadModConf->fileUID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "fileownernum")) { + loadModConf->fileUID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "filegroup")) { + loadModConf->fileGID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "filegroupnum")) { + loadModConf->fileGID = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "dynafile.donotsuspend")) { + loadModConf->bDynafileDoNotSuspend = (int) pvals[i].val.d.n; + } else { + dbgprintf("omfile: program error, non-handled " + "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); + } + } +finalize_it: + if(pvals != NULL) + cnfparamvalsDestruct(pvals, &modpblk); +ENDsetModCnf + +/* This function checks dynafile cache for janitor action */ +static void +janitorChkDynaFiles(instanceData *__restrict__ const pData) +{ + uint i; + dynaFileCacheEntry **pCache = pData->dynCache; + + for(i = 0 ; i < pData->iCurrCacheSize ; ++i) { + if(pCache[i] == NULL) + continue; + DBGPRINTF("omfile janitor: checking dynafile %d:%s, inactive since %d\n", i, + pCache[i]->pName == NULL ? UCHAR_CONSTANT("[OPEN FAILED]") : pCache[i]->pName, + (int) pCache[i]->nInactive); + if(pCache[i]->nInactive >= pData->iCloseTimeout) { + STATSCOUNTER_INC(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); + dynaFileDelCacheEntry(pData, i, 1); + if(pData->iCurrElt >= 0) { + if((uint)(pData->iCurrElt) == i) + pData->iCurrElt = -1; /* no longer available! */ + } + } else { + pCache[i]->nInactive += runModConf->pConf->globals.janitorInterval; + } + } +} + +/* callback for the janitor. This cleans out files (if so configured) */ +static void +janitorCB(void *pUsr) +{ + instanceData *__restrict__ const pData = (instanceData *) pUsr; + pthread_mutex_lock(&pData->mutWrite); + if(pData->bDynamicName) { + janitorChkDynaFiles(pData); + } else { + if(pData->pStrm != NULL) { + DBGPRINTF("omfile janitor: checking file %s, inactive since %d\n", + pData->fname, pData->nInactive); + if(pData->nInactive >= pData->iCloseTimeout) { + STATSCOUNTER_INC(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); + closeFile(pData); + } else { + pData->nInactive += runModConf->pConf->globals.janitorInterval; + } + } + } + pthread_mutex_unlock(&pData->mutWrite); +} + + +BEGINendCnfLoad +CODESTARTendCnfLoad + loadModConf = NULL; /* done loading */ + /* free legacy config vars */ + free(pszFileDfltTplName); + pszFileDfltTplName = NULL; +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf + runModConf = pModConf; +ENDactivateCnf + +BEGINfreeCnf +CODESTARTfreeCnf + free(pModConf->tplName); +ENDfreeCnf + + +BEGINcreateInstance +CODESTARTcreateInstance + pData->pStrm = NULL; + pthread_mutex_init(&pData->mutWrite, NULL); +ENDcreateInstance + + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + + +BEGINfreeInstance +CODESTARTfreeInstance + free(pData->tplName); + free(pData->fname); + if(pData->iCloseTimeout > 0) + janitorDelEtry(pData->janitorID); + if(pData->bDynamicName) { + dynaFileFreeCache(pData); + } else if(pData->pStrm != NULL) + closeFile(pData); + if(pData->stats != NULL) + statsobj.Destruct(&(pData->stats)); + if(pData->useSigprov) { + pData->sigprov.Destruct(&pData->sigprovData); + obj.ReleaseObj(__FILE__, pData->sigprovNameFull+2, pData->sigprovNameFull, + (void*) &pData->sigprov); + free(pData->sigprovName); + free(pData->sigprovNameFull); + } + if(pData->useCryprov) { + pData->cryprov.Destruct(&pData->cryprovData); + obj.ReleaseObj(__FILE__, pData->cryprovNameFull+2, pData->cryprovNameFull, + (void*) &pData->cryprov); + free(pData->cryprovName); + free(pData->cryprovNameFull); + } + pthread_mutex_destroy(&pData->mutWrite); +ENDfreeInstance + + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +BEGINbeginTransaction +CODESTARTbeginTransaction + /* we have nothing to do to begin a transaction */ +ENDbeginTransaction + + +BEGINcommitTransaction + instanceData *__restrict__ const pData = pWrkrData->pData; + unsigned i; +CODESTARTcommitTransaction + pthread_mutex_lock(&pData->mutWrite); + + for(i = 0 ; i < nParams ; ++i) { + CHKiRet(writeFile(pData, pParams, i)); + } + /* Note: pStrm may be NULL if there was an error opening the stream */ + /* if bFlushOnTXEnd is set, we need to flush on transaction end - in + * any case. It is not relevant if this is using background writes + * (which then become pretty slow) or not. And, similarly, no flush + * happens when it is not set. Please see + * https://github.com/rsyslog/rsyslog/issues/1297 + * for a discussion of why we actually need this. + * rgerhards, 2017-01-13 + */ + if(pData->bFlushOnTXEnd && pData->pStrm != NULL) { + CHKiRet(strm.Flush(pData->pStrm)); + } + +finalize_it: + if (iRet != RS_RET_OK) { + if (runModConf->bDynafileDoNotSuspend == 0 || !(pData->bDynamicName)) { + LogError(0, iRet, "suspending action"); + iRet = RS_RET_SUSPENDED; + } + else { + LogError(0, iRet, "discarding message"); + } + } + pthread_mutex_unlock(&pData->mutWrite); +ENDcommitTransaction + + +static void +setInstParamDefaults(instanceData *__restrict__ const pData) +{ + pData->fname = NULL; + pData->tplName = NULL; + pData->fileUID = loadModConf->fileUID; + pData->fileGID = loadModConf->fileGID; + pData->dirUID = loadModConf->dirUID; + pData->dirGID = loadModConf->dirGID; + pData->bFailOnChown = 1; + pData->iDynaFileCacheSize = 10; + pData->fCreateMode = loadModConf->fCreateMode; + pData->fDirCreateMode = loadModConf->fDirCreateMode; + pData->bCreateDirs = 1; + pData->bSyncFile = 0; + pData->iZipLevel = 0; + pData->bVeryRobustZip = 0; + pData->bFlushOnTXEnd = FLUSHONTX_DFLT; + pData->iIOBufSize = IOBUF_DFLT_SIZE; + pData->iFlushInterval = FLUSH_INTRVL_DFLT; + pData->bUseAsyncWriter = USE_ASYNCWRITER_DFLT; + pData->sigprovName = NULL; + pData->cryprovName = NULL; + pData->useSigprov = 0; + pData->useCryprov = 0; + pData->iCloseTimeout = -1; +} + + +static rsRetVal +setupInstStatsCtrs(instanceData *__restrict__ const pData) +{ + uchar ctrName[512]; + DEFiRet; + + if(!pData->bDynamicName) { + FINALIZE; + } + + /* support statistics gathering */ + snprintf((char*)ctrName, sizeof(ctrName), "dynafile cache %s", pData->fname); + ctrName[sizeof(ctrName)-1] = '\0'; /* be on the save side */ + CHKiRet(statsobj.Construct(&(pData->stats))); + CHKiRet(statsobj.SetName(pData->stats, ctrName)); + CHKiRet(statsobj.SetOrigin(pData->stats, (uchar*)"omfile")); + STATSCOUNTER_INIT(pData->ctrRequests, pData->mutCtrRequests); + CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("requests"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrRequests))); + STATSCOUNTER_INIT(pData->ctrLevel0, pData->mutCtrLevel0); + CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("level0"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrLevel0))); + STATSCOUNTER_INIT(pData->ctrMiss, pData->mutCtrMiss); + CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("missed"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrMiss))); + STATSCOUNTER_INIT(pData->ctrEvict, pData->mutCtrEvict); + CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("evicted"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrEvict))); + STATSCOUNTER_INIT(pData->ctrMax, pData->mutCtrMax); + CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("maxused"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrMax))); + STATSCOUNTER_INIT(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); + CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("closetimeouts"), + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrCloseTimeouts))); + CHKiRet(statsobj.ConstructFinalize(pData->stats)); + +finalize_it: + RETiRet; +} + +static void +initSigprov(instanceData *__restrict__ const pData, struct nvlst *lst) +{ + uchar szDrvrName[1024]; + + if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmsig_%s", pData->sigprovName) + == sizeof(szDrvrName)) { + parser_errmsg("omfile: signature provider " + "name is too long: '%s' - signatures disabled", + pData->sigprovName); + goto done; + } + pData->sigprovNameFull = ustrdup(szDrvrName); + + pData->sigprov.ifVersion = sigprovCURR_IF_VERSION; + /* The pDrvrName+2 below is a hack to obtain the object name. It + * safes us to have yet another variable with the name without "lm" in + * front of it. If we change the module load interface, we may re-think + * about this hack, but for the time being it is efficient and clean enough. + */ + if(obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void*) &pData->sigprov) + != RS_RET_OK) { + parser_errmsg("omfile: could not load " + "signature provider '%s' - signatures disabled", + szDrvrName); + goto done; + } + + if(pData->sigprov.Construct(&pData->sigprovData) != RS_RET_OK) { + parser_errmsg("omfile: error constructing " + "signature provider %s dataset - signatures disabled", + szDrvrName); + goto done; + } + pData->sigprov.SetCnfParam(pData->sigprovData, lst); + + dbgprintf("loaded signature provider %s, data instance at %p\n", + szDrvrName, pData->sigprovData); + pData->useSigprov = 1; +done: return; +} + +static rsRetVal +initCryprov(instanceData *__restrict__ const pData, struct nvlst *lst) +{ + uchar szDrvrName[1024]; + DEFiRet; + + if(snprintf((char*)szDrvrName, sizeof(szDrvrName), "lmcry_%s", pData->cryprovName) + == sizeof(szDrvrName)) { + parser_errmsg("omfile: crypto provider " + "name is too long: '%s' - encryption disabled", + pData->cryprovName); + ABORT_FINALIZE(RS_RET_ERR); + } + pData->cryprovNameFull = ustrdup(szDrvrName); + + pData->cryprov.ifVersion = cryprovCURR_IF_VERSION; + /* The pDrvrName+2 below is a hack to obtain the object name. It + * safes us to have yet another variable with the name without "lm" in + * front of it. If we change the module load interface, we may re-think + * about this hack, but for the time being it is efficient and clean enough. + */ + if(obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void*) &pData->cryprov) + != RS_RET_OK) { + parser_errmsg("omfile: could not load " + "crypto provider '%s' - encryption disabled", + szDrvrName); + ABORT_FINALIZE(RS_RET_CRYPROV_ERR); + } + + if(pData->cryprov.Construct(&pData->cryprovData) != RS_RET_OK) { + parser_errmsg("omfile: error constructing " + "crypto provider %s dataset - encryption disabled", + szDrvrName); + ABORT_FINALIZE(RS_RET_CRYPROV_ERR); + } + CHKiRet(pData->cryprov.SetCnfParam(pData->cryprovData, lst, CRYPROV_PARAMTYPE_REGULAR)); + + dbgprintf("loaded crypto provider %s, data instance at %p\n", + szDrvrName, pData->cryprovData); + pData->useCryprov = 1; +finalize_it: + RETiRet; +} + +BEGINnewActInst + struct cnfparamvals *pvals; + uchar *tplToUse; + int i; +CODESTARTnewActInst + DBGPRINTF("newActInst (omfile)\n"); + + pvals = nvlstGetParams(lst, &actpblk, NULL); + if(pvals == NULL) { + parser_errmsg("omfile: either the \"file\" or " + "\"dynafile\" parameter must be given"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("action param blk in omfile:\n"); + cnfparamsPrint(&actpblk, pvals); + } + + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(actpblk.descr[i].name, "dynafilecachesize")) { + pData->iDynaFileCacheSize = (uint) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "ziplevel")) { + pData->iZipLevel = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "flushinterval")) { + pData->iFlushInterval = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "veryrobustzip")) { + pData->bVeryRobustZip = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "asyncwriting")) { + pData->bUseAsyncWriter = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "flushontxend")) { + pData->bFlushOnTXEnd = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "iobuffersize")) { + pData->iIOBufSize = (uint) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "dirowner")) { + pData->dirUID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "dirownernum")) { + pData->dirUID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "dirgroup")) { + pData->dirGID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "dirgroupnum")) { + pData->dirGID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "fileowner")) { + pData->fileUID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "fileownernum")) { + pData->fileUID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "filegroup")) { + pData->fileGID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "filegroupnum")) { + pData->fileGID = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "dircreatemode")) { + pData->fDirCreateMode = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "filecreatemode")) { + pData->fCreateMode = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "failonchownfailure")) { + pData->bFailOnChown = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "sync")) { + pData->bSyncFile = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "createdirs")) { + pData->bCreateDirs = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "file")) { + pData->fname = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + CODE_STD_STRING_REQUESTnewActInst(1) + pData->bDynamicName = 0; + } else if(!strcmp(actpblk.descr[i].name, "dynafile")) { + if(pData->fname != NULL) { + parser_errmsg("omfile: both \"file\" and \"dynafile\" set, will use dynafile"); + } + pData->fname = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + CODE_STD_STRING_REQUESTnewActInst(2) + pData->bDynamicName = 1; + } else if(!strcmp(actpblk.descr[i].name, "template")) { + pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "sig.provider")) { + pData->sigprovName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "cry.provider")) { + pData->cryprovName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "closetimeout")) { + pData->iCloseTimeout = (int) pvals[i].val.d.n; + } else { + dbgprintf("omfile: program error, non-handled " + "param '%s'\n", actpblk.descr[i].name); + } + } + + if(pData->fname == NULL) { + parser_errmsg("omfile: either the \"file\" or " + "\"dynafile\" parameter must be given"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(pData->sigprovName != NULL) { + initSigprov(pData, lst); + } + + if(pData->cryprovName != NULL) { + CHKiRet(initCryprov(pData, lst)); + } + + tplToUse = ustrdup((pData->tplName == NULL) ? getDfltTpl() : pData->tplName); + CHKiRet(OMSRsetEntry(*ppOMSR, 0, tplToUse, OMSR_NO_RQD_TPL_OPTS)); + pData->iNumTpls = 1; + + if(pData->bDynamicName) { + /* "filename" is actually a template name, we need this as string 1. So let's add it + * to the pOMSR. -- rgerhards, 2007-07-27 + */ + CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->fname), OMSR_NO_RQD_TPL_OPTS)); + pData->iNumTpls = 2; + // TODO: create unified code for this (legacy+v6 system) + /* we now allocate the cache table */ + CHKmalloc(pData->dynCache = (dynaFileCacheEntry**) + calloc(pData->iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))); + pData->iCurrElt = -1; /* no current element */ + } +// TODO: add pData->iSizeLimit = 0; /* default value, use outchannels to configure! */ + setupInstStatsCtrs(pData); + + if(pData->iCloseTimeout == -1) { /* unset? */ + pData->iCloseTimeout = (pData->bDynamicName) ? 10 : 0; + } + + snprintf(pData->janitorID, sizeof(pData->janitorID), "omfile:%sfile:%s:%p", + (pData->bDynamicName) ? "dyna" : "", pData->fname, pData); + pData->janitorID[sizeof(pData->janitorID)-1] = '\0'; /* just in case... */ + + if(pData->iCloseTimeout > 0) + janitorAddEtry(janitorCB, pData->janitorID, pData); + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + + +BEGINparseSelectorAct + uchar fname[MAXFNAME]; +CODESTARTparseSelectorAct + /* Note: the indicator sequence permits us to use '$' to signify + * outchannel, what otherwise is not possible due to truely + * unresolvable grammar conflicts (*this time no way around*). + * rgerhards, 2011-07-09 + */ + if(!strncmp((char*) p, ":omfile:", sizeof(":omfile:") - 1)) { + p += sizeof(":omfile:") - 1; + } + if(!(*p == '$' || *p == '?' || *p == '/' || *p == '.' || *p == '-')) + ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); + + CHKiRet(createInstance(&pData)); + + if(*p == '-') { + pData->bSyncFile = 0; + p++; + } else { + pData->bSyncFile = cs.bEnableSync; + } + pData->iSizeLimit = 0; /* default value, use outchannels to configure! */ + + switch(*p) { + case '$': + CODE_STD_STRING_REQUESTparseSelectorAct(1) + pData->iNumTpls = 1; + /* rgerhards 2005-06-21: this is a special setting for output-channel + * definitions. In the long term, this setting will probably replace + * anything else, but for the time being we must co-exist with the + * traditional mode lines. + * rgerhards, 2007-07-24: output-channels will go away. We keep them + * for compatibility reasons, but seems to have been a bad idea. + */ + CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); + pData->bDynamicName = 0; + break; + + case '?': /* This is much like a regular file handle, but we need to obtain + * a template name. rgerhards, 2007-07-03 + */ + CODE_STD_STRING_REQUESTparseSelectorAct(2) + pData->iNumTpls = 2; + ++p; /* eat '?' */ + CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); + pData->fname = ustrdup(fname); + pData->bDynamicName = 1; + pData->iCurrElt = -1; /* no current element */ + /* "filename" is actually a template name, we need this as string 1. So let's add it + * to the pOMSR. -- rgerhards, 2007-07-27 + */ + CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->fname), OMSR_NO_RQD_TPL_OPTS)); + /* we now allocate the cache table */ + CHKmalloc(pData->dynCache = (dynaFileCacheEntry**) + calloc(cs.iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))); + break; + + case '/': + case '.': + CODE_STD_STRING_REQUESTparseSelectorAct(1) + pData->iNumTpls = 1; + CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); + pData->fname = ustrdup(fname); + pData->bDynamicName = 0; + break; + default: + ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); + } + + /* freeze current paremeters for this action */ + pData->iDynaFileCacheSize = cs.iDynaFileCacheSize; + pData->fCreateMode = cs.fCreateMode; + pData->fDirCreateMode = cs.fDirCreateMode; + pData->bCreateDirs = cs.bCreateDirs; + pData->bFailOnChown = cs.bFailOnChown; + pData->fileUID = cs.fileUID; + pData->fileGID = cs.fileGID; + pData->dirUID = cs.dirUID; + pData->dirGID = cs.dirGID; + pData->iZipLevel = cs.iZipLevel; + pData->bFlushOnTXEnd = cs.bFlushOnTXEnd; + pData->iIOBufSize = (uint) cs.iIOBufSize; + pData->iFlushInterval = cs.iFlushInterval; + pData->bUseAsyncWriter = cs.bUseAsyncWriter; + pData->bVeryRobustZip = 0; /* cannot be specified via legacy conf */ + pData->iCloseTimeout = 0; /* cannot be specified via legacy conf */ + setupInstStatsCtrs(pData); +CODE_STD_FINALIZERparseSelectorAct +ENDparseSelectorAct + + +/* Reset config variables for this module to default values. + * rgerhards, 2007-07-17 + */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + cs.fileUID = -1; + cs.fileGID = -1; + cs.dirUID = -1; + cs.dirGID = -1; + cs.bFailOnChown = 1; + cs.iDynaFileCacheSize = 10; + cs.fCreateMode = 0644; + cs.fDirCreateMode = 0700; + cs.bCreateDirs = 1; + cs.bEnableSync = 0; + cs.iZipLevel = 0; + cs.bFlushOnTXEnd = FLUSHONTX_DFLT; + cs.iIOBufSize = IOBUF_DFLT_SIZE; + cs.iFlushInterval = FLUSH_INTRVL_DFLT; + cs.bUseAsyncWriter = USE_ASYNCWRITER_DFLT; + free(pszFileDfltTplName); + pszFileDfltTplName = NULL; + return RS_RET_OK; +} + + +BEGINdoHUP +CODESTARTdoHUP + pthread_mutex_lock(&pData->mutWrite); + if(pData->bDynamicName) { + dynaFileFreeCacheEntries(pData); + } else { + if(pData->pStrm != NULL) { + closeFile(pData); + } + } + pthread_mutex_unlock(&pData->mutWrite); +ENDdoHUP + + +BEGINmodExit +CODESTARTmodExit + objRelease(glbl, CORE_COMPONENT); + objRelease(strm, CORE_COMPONENT); + objRelease(statsobj, CORE_COMPONENT); + DESTROY_ATOMIC_HELPER_MUT(mutClock); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMODTX_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_doHUP +ENDqueryEtryPt + + +BEGINmodInit(File) +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr +INITLegCnfVars + CHKiRet(objUse(strm, CORE_COMPONENT)); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); + + INIT_ATOMIC_HELPER_MUT(mutClock); + + INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); + DBGPRINTF("omfile: %susing transactional output interface.\n", bCoreSupportsBatching ? "" : "not "); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dynafilecachesize", 0, eCmdHdlrInt, setDynaFileCacheSize, + NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileziplevel", 0, eCmdHdlrInt, NULL, &cs.iZipLevel, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushinterval", 0, eCmdHdlrInt, NULL, &cs.iFlushInterval, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileasyncwriting", 0, eCmdHdlrBinary, NULL, &cs.bUseAsyncWriter, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushontxend", 0, eCmdHdlrBinary, NULL, &cs.bFlushOnTXEnd, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileiobuffersize", 0, eCmdHdlrSize, NULL, &cs.iIOBufSize, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirowner", 0, eCmdHdlrUID, NULL, &cs.dirUID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirownernum", 0, eCmdHdlrInt, NULL, &cs.dirUID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroup", 0, eCmdHdlrGID, NULL, &cs.dirGID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroupnum", 0, eCmdHdlrInt, NULL, &cs.dirGID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileowner", 0, eCmdHdlrUID, NULL, &cs.fileUID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileownernum", 0, eCmdHdlrInt, NULL, &cs.fileUID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroup", 0, eCmdHdlrGID, NULL, &cs.fileGID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroupnum", 0, eCmdHdlrInt, NULL, &cs.fileGID, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"dircreatemode", 0, eCmdHdlrFileCreateMode, NULL, + &cs.fDirCreateMode, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"filecreatemode", 0, eCmdHdlrFileCreateMode, NULL, + &cs.fCreateMode, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"createdirs", 0, eCmdHdlrBinary, NULL, &cs.bCreateDirs, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &cs.bFailOnChown, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileforcechown", 0, eCmdHdlrGoneAway, NULL, NULL, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &cs.bEnableSync, + STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, setLegacyDfltTpl, + NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, + NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(objUse(glbl, CORE_COMPONENT)); +ENDmodInit diff --git a/contrib/omhiredis/COPYING b/contrib/omhiredis/COPYING new file mode 100644 index 0000000..f44bd49 --- /dev/null +++ b/contrib/omhiredis/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/contrib/omhiredis/Makefile.am b/contrib/omhiredis/Makefile.am new file mode 100644 index 0000000..2332be4 --- /dev/null +++ b/contrib/omhiredis/Makefile.am @@ -0,0 +1,7 @@ +pkglib_LTLIBRARIES = omhiredis.la +omhiredis_la_SOURCES = omhiredis.c +omhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) +omhiredis_la_LDFLAGS = -module -avoid-version +omhiredis_la_LIBADD = $(HIREDIS_LIBS) + +EXTRA_DIST = diff --git a/contrib/omhiredis/Makefile.in b/contrib/omhiredis/Makefile.in new file mode 100644 index 0000000..8ac13e7 --- /dev/null +++ b/contrib/omhiredis/Makefile.in @@ -0,0 +1,799 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omhiredis +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +omhiredis_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_omhiredis_la_OBJECTS = omhiredis_la-omhiredis.lo +omhiredis_la_OBJECTS = $(am_omhiredis_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omhiredis_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(omhiredis_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/omhiredis_la-omhiredis.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omhiredis_la_SOURCES) +DIST_SOURCES = $(omhiredis_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING \ + README +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omhiredis.la +omhiredis_la_SOURCES = omhiredis.c +omhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) +omhiredis_la_LDFLAGS = -module -avoid-version +omhiredis_la_LIBADD = $(HIREDIS_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omhiredis/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omhiredis/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omhiredis.la: $(omhiredis_la_OBJECTS) $(omhiredis_la_DEPENDENCIES) $(EXTRA_omhiredis_la_DEPENDENCIES) + $(AM_V_CCLD)$(omhiredis_la_LINK) -rpath $(pkglibdir) $(omhiredis_la_OBJECTS) $(omhiredis_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omhiredis_la-omhiredis.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omhiredis_la-omhiredis.lo: omhiredis.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omhiredis_la-omhiredis.lo -MD -MP -MF $(DEPDIR)/omhiredis_la-omhiredis.Tpo -c -o omhiredis_la-omhiredis.lo `test -f 'omhiredis.c' || echo '$(srcdir)/'`omhiredis.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omhiredis_la-omhiredis.Tpo $(DEPDIR)/omhiredis_la-omhiredis.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omhiredis.c' object='omhiredis_la-omhiredis.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omhiredis_la-omhiredis.lo `test -f 'omhiredis.c' || echo '$(srcdir)/'`omhiredis.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omhiredis_la-omhiredis.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omhiredis_la-omhiredis.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omhiredis/README b/contrib/omhiredis/README new file mode 100644 index 0000000..56b7030 --- /dev/null +++ b/contrib/omhiredis/README @@ -0,0 +1,70 @@ +Redis Outplug Plugin using hiredis library + +REQUIREMENTS: + +* hiredis ( https://github.com/redis/hiredis.git ) + +USAGE: + +This plugin has three current "modes" that it supports: + +1. "template" + +This is the original mode that the plugin supported. You use an rsyslog template +to construct a command that is sent directly to redis. This mode currently has +an issue dealing with strings that contain spaces. It's useful for doing things +like incrementing counters for statistics. + +``` +module(load="omhiredis") + +template( + name="simple_count" + type="string" + string="HINCRBY testcount %programname% 1") + +*.* action( + name="count_redis" + type="omhiredis" + mode="template" + template="simple_count" + ) +``` + +2. "queue" +The queue mode will LPUSH your message to a redis list. Unlike the template +mode, it handles full rsyslog messages properly. If a template is not +supplied, it will default to the RSYSLOG_ForwardFormat template. The "key" +parameter is required. + +``` +module(load="omhiredis") + +*.* action( + name="push_redis" + type="omhiredis" + mode="queue" + key="testqueue" + ) +``` + +3. "publish" +The publish mode will PUBLISH to a redis channel. Unlike the template mode, +it handles full rsyslog messages properly. If a template is not supplied, +it will default to the RSYSLOG_ForwardFormat template. The "key" +parameter is required and will be used for the publish channel. + +``` +module(load="omhiredis") + +*.* action( + name="publish_redis" + type="omhiredis" + mode="publish" + key="testpublish" + ) +``` + + +NOTES +* dequeuebatchsize now sets the pipeline size for hiredis, allowing pipelining commands. diff --git a/contrib/omhiredis/omhiredis.c b/contrib/omhiredis/omhiredis.c new file mode 100644 index 0000000..eb22ed8 --- /dev/null +++ b/contrib/omhiredis/omhiredis.c @@ -0,0 +1,753 @@ +/* omhiredis.c +* Copyright 2012 Talksum, Inc +* Copyright 2015 DigitalOcean, Inc +* +* This program is free software: you can redistribute it and/or +* modify it under the terms of the GNU Lesser 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this program. If not, see +* <http://www.gnu.org/licenses/>. +* +* Author: Brian Knox +* <bknox@digitalocean.com> +*/ + + +#include "config.h" +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <errno.h> +#include <assert.h> +#include <signal.h> +#include <time.h> +#include <math.h> +#include <hiredis/hiredis.h> + +#include "rsyslog.h" +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "unicode-helper.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omhiredis") +/* internal structures + */ +DEF_OMOD_STATIC_DATA + +#define OMHIREDIS_MODE_TEMPLATE 0 +#define OMHIREDIS_MODE_QUEUE 1 +#define OMHIREDIS_MODE_PUBLISH 2 +#define OMHIREDIS_MODE_SET 3 +#define OMHIREDIS_MODE_STREAM 4 + +/* our instance data. + * this will be accessable + * via pData */ +typedef struct _instanceData { + uchar *server; /* redis server address */ + int port; /* redis port */ + uchar *serverpassword; /* redis password */ + uchar *tplName; /* template name */ + char *modeDescription; /* mode description */ + int mode; /* mode constant */ + uchar *key; /* key for QUEUE, PUBLISH and STREAM modes */ + uchar *streamKeyAck; /* key name for STREAM ACKs (when enabled) */ + uchar *streamGroupAck; /* group name for STREAM ACKs (when enabled) */ + uchar *streamIndexAck; /* index name for STREAM ACKs (when enabled) */ + int expiration; /* expiration value for SET/SETEX mode */ + sbool dynaKey; /* Should we treat the key as a template? */ + sbool streamDynaKeyAck; /* Should we treat the groupAck as a template? */ + sbool streamDynaGroupAck; /* Should we treat the groupAck as a template? */ + sbool streamDynaIndexAck; /* Should we treat the IndexAck as a template? */ + sbool useRPush; /* Should we use RPUSH instead of LPUSH? */ + uchar *streamOutField; /* Field to place message into (for stream insertions only) */ + uint streamCapacityLimit; /* zero means stream is not capped (default) + setting a non-zero value ultimately activates the approximate MAXLEN option '~' + (see Redis XADD docs)*/ + sbool streamAck; /* Should the module send an XACK for each inserted message? + This feature requires that 3 infos are present in the '$.' object of the log: + - $.redis!stream + - $.redis!group + - $.redis!index + Those 3 infos can either be provided through usage of imhiredis + or set manually with Rainerscript */ + sbool streamDel; /* Should the module send an XDEL for each inserted message? + This feature requires that 2 infos are present in the '$.' object of the log: + - $.redis!stream + - $.redis!index + Those 2 infos can either be provided through usage of imhiredis + or set manually with Rainerscript */ + +} instanceData; + +typedef struct wrkrInstanceData { + instanceData *pData; /* instanc data */ + redisContext *conn; /* redis connection */ + int count; /* count of command sent for current batch */ +} wrkrInstanceData_t; + +static struct cnfparamdescr actpdescr[] = { + { "server", eCmdHdlrGetWord, 0 }, + { "serverport", eCmdHdlrInt, 0 }, + { "serverpassword", eCmdHdlrGetWord, 0 }, + { "template", eCmdHdlrGetWord, 0 }, + { "mode", eCmdHdlrGetWord, 0 }, + { "key", eCmdHdlrGetWord, 0 }, + { "expiration", eCmdHdlrInt, 0 }, + { "dynakey", eCmdHdlrBinary, 0 }, + { "userpush", eCmdHdlrBinary, 0 }, + { "stream.outField", eCmdHdlrGetWord, 0 }, + { "stream.capacityLimit", eCmdHdlrNonNegInt, 0 }, + { "stream.ack", eCmdHdlrBinary, 0 }, + { "stream.del", eCmdHdlrBinary, 0 }, + { "stream.keyAck", eCmdHdlrGetWord, 0 }, + { "stream.groupAck", eCmdHdlrGetWord, 0 }, + { "stream.indexAck", eCmdHdlrGetWord, 0 }, + { "stream.dynaKeyAck", eCmdHdlrBinary, 0 }, + { "stream.dynaGroupAck", eCmdHdlrBinary, 0 }, + { "stream.dynaIndexAck", eCmdHdlrBinary, 0 }, +}; + +static struct cnfparamblk actpblk = { + CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr +}; + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance + pWrkrData->conn = NULL; /* Connect later */ +ENDcreateWrkrInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURERepeatedMsgReduction) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +/* called when closing */ +static void closeHiredis(wrkrInstanceData_t *pWrkrData) +{ + if(pWrkrData->conn != NULL) { + redisFree(pWrkrData->conn); + pWrkrData->conn = NULL; + } +} + +/* Free our instance data. */ +BEGINfreeInstance +CODESTARTfreeInstance + if (pData->server != NULL) { + free(pData->server); + } + free(pData->key); + free(pData->modeDescription); + free(pData->serverpassword); + free(pData->tplName); + free(pData->streamKeyAck); + free(pData->streamGroupAck); + free(pData->streamIndexAck); + free(pData->streamOutField); +ENDfreeInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance + closeHiredis(pWrkrData); +ENDfreeWrkrInstance + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + /* nothing special here */ +ENDdbgPrintInstInfo + +/* establish our connection to redis */ +static rsRetVal initHiredis(wrkrInstanceData_t *pWrkrData, int bSilent) +{ + char *server; + redisReply *reply = NULL; + DEFiRet; + + server = (pWrkrData->pData->server == NULL) ? (char *)"127.0.0.1" : + (char*) pWrkrData->pData->server; + DBGPRINTF("omhiredis: trying connect to '%s' at port %d\n", server, + pWrkrData->pData->port); + + struct timeval timeout = { 1, 500000 }; /* 1.5 seconds */ + pWrkrData->conn = redisConnectWithTimeout(server, pWrkrData->pData->port, + timeout); + if (pWrkrData->conn->err) { + if(!bSilent) + LogError(0, RS_RET_SUSPENDED, + "can not initialize redis handle"); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + + if (pWrkrData->pData->serverpassword != NULL) { + reply = redisCommand(pWrkrData->conn, "AUTH %s", (char*) pWrkrData->pData->serverpassword); + if (reply == NULL) { + DBGPRINTF("omhiredis: could not get reply from AUTH command\n"); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + else if (reply->type == REDIS_REPLY_ERROR) { + LogError(0, NO_ERRCODE, "omhiredis: error while authenticating: %s", reply->str); + ABORT_FINALIZE(RS_RET_ERR); + } + } + +finalize_it: + if (iRet != RS_RET_OK && pWrkrData-> conn != NULL) { + redisFree(pWrkrData->conn); + pWrkrData->conn = NULL; + } + if (reply != NULL) freeReplyObject(reply); + RETiRet; +} + +static rsRetVal isMaster(wrkrInstanceData_t *pWrkrData) { + DEFiRet; + redisReply *reply = NULL; + + assert(pWrkrData->conn != NULL); + + reply = redisCommand(pWrkrData->conn, "ROLE"); + if (reply == NULL) { + DBGPRINTF("omhiredis: could not get reply from ROLE command\n"); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + else if (reply->type == REDIS_REPLY_ERROR) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "omhiredis: got an error while querying role -> " + "%s\n", reply->str); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + else if (reply->type != REDIS_REPLY_ARRAY || reply->element[0]->type != REDIS_REPLY_STRING) { + LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "omhiredis: did not get a proper reply from ROLE command"); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + else { + if (strncmp(reply->element[0]->str, "master", 6)) { + LogMsg(0, RS_RET_OK, LOG_WARNING, "omhiredis: current connected node is not a master"); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + } + +finalize_it: + free(reply); + RETiRet; +} + +static rsRetVal writeHiredis(uchar* key, uchar *message, wrkrInstanceData_t *pWrkrData) +{ + DEFiRet; + int rc, expire; + size_t msgLen; + char *formattedMsg = NULL; + + /* if we do not have a redis connection, call + * initHiredis and try to establish one */ + if(pWrkrData->conn == NULL) + CHKiRet(initHiredis(pWrkrData, 0)); + + /* try to append the command to the pipeline. + * REDIS_ERR reply indicates something bad + * happened, in which case abort. otherwise + * increase our current pipeline count + * by 1 and continue. */ + switch(pWrkrData->pData->mode) { + case OMHIREDIS_MODE_TEMPLATE: + rc = redisAppendCommand(pWrkrData->conn, (char*)message); + break; + case OMHIREDIS_MODE_QUEUE: + rc = redisAppendCommand(pWrkrData->conn, + pWrkrData->pData->useRPush ? "RPUSH %s %s" : "LPUSH %s %s", + key, (char*)message); + break; + case OMHIREDIS_MODE_PUBLISH: + rc = redisAppendCommand(pWrkrData->conn, "PUBLISH %s %s", key, (char*)message); + break; + case OMHIREDIS_MODE_SET: + expire = pWrkrData->pData->expiration; + + if (expire > 0) + msgLen = redisFormatCommand(&formattedMsg, "SETEX %s %d %s", key, expire, message); + else + msgLen = redisFormatCommand(&formattedMsg, "SET %s %s", key, message); + if (msgLen) + rc = redisAppendFormattedCommand(pWrkrData->conn, formattedMsg, msgLen); + else { + dbgprintf("omhiredis: could not append SET command\n"); + rc = REDIS_ERR; + } + break; + case OMHIREDIS_MODE_STREAM: + if (pWrkrData->pData->streamCapacityLimit != 0) { + rc = redisAppendCommand(pWrkrData->conn, "XADD %s MAXLEN ~ %d * %s %s", + key, + pWrkrData->pData->streamCapacityLimit, + pWrkrData->pData->streamOutField, + message); + } else { + rc = redisAppendCommand(pWrkrData->conn, "XADD %s * %s %s", + key, + pWrkrData->pData->streamOutField, + message); + } + break; + default: + dbgprintf("omhiredis: mode %d is invalid something is really wrong\n", + pWrkrData->pData->mode); + ABORT_FINALIZE(RS_RET_ERR); + } + + if (rc == REDIS_ERR) { + LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr); + dbgprintf("omhiredis: %s\n", pWrkrData->conn->errstr); + ABORT_FINALIZE(RS_RET_ERR); + } else { + pWrkrData->count++; + } + +finalize_it: + free(formattedMsg); + RETiRet; +} + +static rsRetVal ackHiredisStreamIndex(wrkrInstanceData_t *pWrkrData, uchar *key, uchar *group, uchar *index) { + DEFiRet; + + if (REDIS_ERR == redisAppendCommand(pWrkrData->conn, "XACK %s %s %s", key, group, index)) { + LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr); + DBGPRINTF("omhiredis: %s\n", pWrkrData->conn->errstr); + ABORT_FINALIZE(RS_RET_ERR); + } else { + pWrkrData->count++; + } + +finalize_it: + RETiRet; +} + +static rsRetVal delHiredisStreamIndex(wrkrInstanceData_t *pWrkrData, uchar *key, uchar *index) { + DEFiRet; + + if (REDIS_ERR == redisAppendCommand(pWrkrData->conn, "XDEL %s %s", key, index)) { + LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr); + DBGPRINTF("omhiredis: %s\n", pWrkrData->conn->errstr); + ABORT_FINALIZE(RS_RET_ERR); + } else { + pWrkrData->count++; + } + +finalize_it: + RETiRet; +} + +/* called when resuming from suspended state. + * try to restablish our connection to redis */ +BEGINtryResume +CODESTARTtryResume + closeHiredis(pWrkrData); + CHKiRet(initHiredis(pWrkrData, 0)); + // Must get a master node for all modes, except 'publish' + if(pWrkrData->pData->mode != OMHIREDIS_MODE_PUBLISH) { + CHKiRet(isMaster(pWrkrData)); + } +finalize_it: +ENDtryResume + +/* begin a transaction. + * if I decide to use MULTI ... EXEC in the + * future, this block should send the + * MULTI command to redis. */ +BEGINbeginTransaction +CODESTARTbeginTransaction + dbgprintf("omhiredis: beginTransaction called\n"); + pWrkrData->count = 0; +ENDbeginTransaction + +/* call writeHiredis for this log line, + * which appends it as a command to the + * current pipeline */ +BEGINdoAction + uchar *message, *key, *keyNameAck, *groupNameAck, *IndexNameAck; + int inputIndex = 0; +CODESTARTdoAction + // Don't change the order of conditions/assignations here without changing the end of the newActInst function! + message = ppString[inputIndex++]; + key = pWrkrData->pData->dynaKey ? ppString[inputIndex++] : pWrkrData->pData->key; + keyNameAck = pWrkrData->pData->streamDynaKeyAck ? ppString[inputIndex++] : pWrkrData->pData->streamKeyAck; + groupNameAck = pWrkrData->pData->streamDynaGroupAck ? ppString[inputIndex++] : pWrkrData->pData->streamGroupAck; + IndexNameAck = pWrkrData->pData->streamDynaIndexAck ? ppString[inputIndex++] : pWrkrData->pData->streamIndexAck; + + CHKiRet(writeHiredis(key, message, pWrkrData)); + + if(pWrkrData->pData->streamAck) { + CHKiRet(ackHiredisStreamIndex(pWrkrData, keyNameAck, groupNameAck, IndexNameAck)); + } + if(pWrkrData->pData->streamDel) { + CHKiRet(delHiredisStreamIndex(pWrkrData, keyNameAck, IndexNameAck)); + } + + iRet = RS_RET_DEFER_COMMIT; +finalize_it: +ENDdoAction + +/* called when we have reached the end of a + * batch (queue.dequeuebatchsize). this + * iterates over the replies, putting them + * into the pData->replies buffer. we currently + * don't really bother to check for errors + * which should be fixed */ +BEGINendTransaction +CODESTARTendTransaction + dbgprintf("omhiredis: endTransaction called\n"); + redisReply *reply; + int i; + for ( i = 0; i < pWrkrData->count; i++ ) { + if( REDIS_OK != redisGetReply( pWrkrData->conn, (void*)&reply) || pWrkrData->conn->err ) { + dbgprintf("omhiredis: %s\n", pWrkrData->conn->errstr); + LogError(0, RS_RET_REDIS_ERROR, "Error while processing replies: %s", pWrkrData->conn->errstr); + closeHiredis(pWrkrData); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + else { + if (reply->type == REDIS_REPLY_ERROR) { + LogError(0, RS_RET_REDIS_ERROR, "Received error from redis -> %s", reply->str); + closeHiredis(pWrkrData); + freeReplyObject(reply); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + freeReplyObject(reply); + } + } + +finalize_it: +ENDendTransaction + +/* set defaults. note server is set to NULL + * and is set to a default in initHiredis if + * it is still null when it's called - I should + * probable just set the default here instead */ +static void +setInstParamDefaults(instanceData *pData) +{ + pData->server = NULL; + pData->port = 6379; + pData->serverpassword = NULL; + pData->tplName = NULL; + pData->mode = OMHIREDIS_MODE_TEMPLATE; + pData->expiration = 0; + pData->modeDescription = NULL; + pData->key = NULL; + pData->dynaKey = 0; + pData->useRPush = 0; + pData->streamOutField = NULL; + pData->streamKeyAck = NULL; + pData->streamDynaKeyAck = 0; + pData->streamGroupAck = NULL; + pData->streamDynaGroupAck = 0; + pData->streamIndexAck = NULL; + pData->streamDynaIndexAck = 0; + pData->streamCapacityLimit = 0; + pData->streamAck = 0; + pData->streamDel = 0; +} + +/* here is where the work to set up a new instance + * is done. this reads the config options from + * the rsyslog conf and takes appropriate setup + * actions. */ +BEGINnewActInst + struct cnfparamvals *pvals; + int i; + int iNumTpls; + uchar *strDup = NULL; +CODESTARTnewActInst + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + + if(!strcmp(actpblk.descr[i].name, "server")) { + pData->server = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "serverport")) { + pData->port = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "serverpassword")) { + pData->serverpassword = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "template")) { + pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "dynakey")) { + pData->dynaKey = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "userpush")) { + pData->useRPush = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "stream.outField")) { + pData->streamOutField = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "stream.keyAck")) { + pData->streamKeyAck = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "stream.dynaKeyAck")) { + pData->streamDynaKeyAck = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "stream.groupAck")) { + pData->streamGroupAck = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "stream.dynaGroupAck")) { + pData->streamDynaGroupAck = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "stream.indexAck")) { + pData->streamIndexAck = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "stream.dynaIndexAck")) { + pData->streamDynaIndexAck = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "stream.capacityLimit")) { + pData->streamCapacityLimit = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "stream.ack")) { + pData->streamAck = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "stream.del")) { + pData->streamDel = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "mode")) { + pData->modeDescription = es_str2cstr(pvals[i].val.d.estr, NULL); + if (!strcmp(pData->modeDescription, "template")) { + pData->mode = OMHIREDIS_MODE_TEMPLATE; + } else if (!strcmp(pData->modeDescription, "queue")) { + pData->mode = OMHIREDIS_MODE_QUEUE; + } else if (!strcmp(pData->modeDescription, "publish")) { + pData->mode = OMHIREDIS_MODE_PUBLISH; + } else if (!strcmp(pData->modeDescription, "set")) { + pData->mode = OMHIREDIS_MODE_SET; + } else if (!strcmp(pData->modeDescription, "stream")) { + pData->mode = OMHIREDIS_MODE_STREAM; + } else { + dbgprintf("omhiredis: unsupported mode %s\n", actpblk.descr[i].name); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + } else if(!strcmp(actpblk.descr[i].name, "key")) { + pData->key = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "expiration")) { + pData->expiration = pvals[i].val.d.n; + dbgprintf("omhiredis: expiration set to %d\n", pData->expiration); + } else { + dbgprintf("omhiredis: program error, non-handled " + "param '%s'\n", actpblk.descr[i].name); + } + } + + dbgprintf("omhiredis: checking config sanity\n"); + + if (!pData->modeDescription) { + dbgprintf("omhiredis: no mode specified, setting it to 'template'\n"); + pData->mode = OMHIREDIS_MODE_TEMPLATE; + } + + if (pData->mode == OMHIREDIS_MODE_STREAM && !pData->streamOutField) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: no stream.outField set, "\ + "using 'msg' as default"); + pData->streamOutField = ustrdup("msg"); + } + + if (pData->tplName == NULL) { + if(pData->mode == OMHIREDIS_MODE_TEMPLATE) { + LogError(0, RS_RET_CONF_PARSE_ERROR, "omhiredis: selected mode requires a template"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } else { + CHKmalloc(pData->tplName = ustrdup("RSYSLOG_ForwardFormat")); + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: no template set, "\ + "using RSYSLOG_ForwardFormat as default"); + } + } + + if (pData->mode != OMHIREDIS_MODE_TEMPLATE && pData->key == NULL) { + + LogError(0, RS_RET_CONF_PARSE_ERROR, + "omhiredis: mode %s requires a key", pData->modeDescription); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if (pData->expiration && pData->mode != OMHIREDIS_MODE_SET) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: expiration set but mode is not "\ + "'set', expiration will be ignored"); + } + + if (pData->mode != OMHIREDIS_MODE_STREAM) { + if (pData->streamOutField) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.outField set "\ + "but mode is not 'stream', field will be ignored"); + } + if (pData->streamAck) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.ack set "\ + "but mode is not 'stream', XACK will be ignored"); + } + if (pData->streamDel) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.del set "\ + "but mode is not 'stream', XDEL will be ignored"); + } + if (pData->streamCapacityLimit) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.capacityLimit set "\ + "but mode is not 'stream', stream trimming will be ignored"); + } + if (pData->streamKeyAck) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.keyAck set "\ + "but mode is not 'stream', parameter will be ignored"); + } + if (pData->streamDynaKeyAck) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.dynaKeyAck set "\ + "but mode is not 'stream', parameter will be ignored"); + } + if (pData->streamGroupAck) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.groupAck set "\ + "but mode is not 'stream', parameter will be ignored"); + } + if (pData->streamDynaGroupAck) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.dynaGroupAck set "\ + "but mode is not 'stream', parameter will be ignored"); + } + if (pData->streamIndexAck) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.indexAck set "\ + "but mode is not 'stream', parameter will be ignored"); + } + if (pData->streamDynaIndexAck) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.dynaIndexAck set "\ + "but mode is not 'stream', parameter will be ignored"); + } + } else { + if(pData->streamAck) { + if(!pData->streamKeyAck || !pData->streamGroupAck || !pData->streamIndexAck) { + LogError(0, RS_RET_CONF_PARSE_ERROR, + "omhiredis: 'stream.ack' is set but one of "\ + "'stream.keyAck', 'stream.groupAck' or 'stream.indexAck' is missing"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + } + if(pData->streamDel) { + if(!pData->streamKeyAck || !pData->streamIndexAck) { + LogError(0, RS_RET_CONF_PARSE_ERROR, + "omhiredis: 'stream.del' is set but one of "\ + "'stream.keyAck' or 'stream.indexAck' is missing"); + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + } + } + + if (pData->streamDynaKeyAck && pData->streamKeyAck == NULL) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: 'stream.dynaKeyAck' set "\ + "but 'stream.keyAck' is empty, disabling"); + pData->streamDynaKeyAck = 0; + } + if (pData->streamDynaGroupAck && pData->streamGroupAck == NULL) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: 'stream.dynaGroupAck' set "\ + "but 'stream.groupAck' is empty, disabling"); + pData->streamDynaGroupAck = 0; + } + if (pData->streamDynaIndexAck && pData->streamIndexAck == NULL) { + LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: 'stream.dynaGroupAck' set "\ + "but 'stream.indexAck' is empty, disabling"); + pData->streamDynaIndexAck = 0; + } + + iNumTpls = 1; + + if (pData->dynaKey) { + assert(pData->key != NULL); + iNumTpls += 1; + } + if (pData->streamDynaKeyAck) { + assert(pData->streamKeyAck != NULL); + iNumTpls += 1; + } + if (pData->streamDynaGroupAck) { + assert(pData->streamGroupAck != NULL); + iNumTpls += 1; + } + if (pData->streamDynaIndexAck) { + assert(pData->streamIndexAck != NULL); + iNumTpls += 1; + } + CODE_STD_STRING_REQUESTnewActInst(iNumTpls); + + /* Insert templates in opposite order (keep in sync with doAction), order will be + * - tplName + * - key + * - streamKeyAck + * - streamGroupAck + * - streamIndexAck + */ + if (pData->streamDynaIndexAck) { + CHKmalloc(strDup = ustrdup(pData->streamIndexAck)); + CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); + strDup = NULL; /* handed over */ + } + + if (pData->streamDynaGroupAck) { + CHKmalloc(strDup = ustrdup(pData->streamGroupAck)); + CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); + strDup = NULL; /* handed over */ + } + + if (pData->streamDynaKeyAck) { + CHKmalloc(strDup = ustrdup(pData->streamKeyAck)); + CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); + strDup = NULL; /* handed over */ + } + + if (pData->dynaKey) { + CHKmalloc(strDup = ustrdup(pData->key)); + CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); + strDup = NULL; /* handed over */ + } + + CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, ustrdup(pData->tplName), OMSR_NO_RQD_TPL_OPTS)); + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); + free(strDup); +ENDnewActInst + + +NO_LEGACY_CONF_parseSelectorAct + + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + +/* register our plugin entry points + * with the rsyslog core engine */ +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_TXIF_OMOD_QUERIES /* supports transaction interface */ +ENDqueryEtryPt + +/* note we do not support rsyslog v5 syntax */ +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* only supports rsyslog 6 configs */ +CODEmodInit_QueryRegCFSLineHdlr + INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); + if (!bCoreSupportsBatching) { + LogError(0, NO_ERRCODE, "omhiredis: rsyslog core does not support batching - abort"); + ABORT_FINALIZE(RS_RET_ERR); + } + DBGPRINTF("omhiredis: module compiled with rsyslog version %s.\n", VERSION); +ENDmodInit diff --git a/contrib/omhttp/Makefile.am b/contrib/omhttp/Makefile.am new file mode 100644 index 0000000..cb29149 --- /dev/null +++ b/contrib/omhttp/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = omhttp.la + +omhttp_la_SOURCES = omhttp.c +omhttp_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) +omhttp_la_LDFLAGS = -module -avoid-version +omhttp_la_LIBADD = $(CURL_LIBS) $(LIBM) + +EXTRA_DIST = diff --git a/contrib/omhttp/Makefile.in b/contrib/omhttp/Makefile.in new file mode 100644 index 0000000..1dc03f3 --- /dev/null +++ b/contrib/omhttp/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omhttp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +omhttp_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_omhttp_la_OBJECTS = omhttp_la-omhttp.lo +omhttp_la_OBJECTS = $(am_omhttp_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omhttp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(omhttp_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/omhttp_la-omhttp.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omhttp_la_SOURCES) +DIST_SOURCES = $(omhttp_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omhttp.la +omhttp_la_SOURCES = omhttp.c +omhttp_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) +omhttp_la_LDFLAGS = -module -avoid-version +omhttp_la_LIBADD = $(CURL_LIBS) $(LIBM) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omhttp/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omhttp/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omhttp.la: $(omhttp_la_OBJECTS) $(omhttp_la_DEPENDENCIES) $(EXTRA_omhttp_la_DEPENDENCIES) + $(AM_V_CCLD)$(omhttp_la_LINK) -rpath $(pkglibdir) $(omhttp_la_OBJECTS) $(omhttp_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omhttp_la-omhttp.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omhttp_la-omhttp.lo: omhttp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omhttp_la-omhttp.lo -MD -MP -MF $(DEPDIR)/omhttp_la-omhttp.Tpo -c -o omhttp_la-omhttp.lo `test -f 'omhttp.c' || echo '$(srcdir)/'`omhttp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omhttp_la-omhttp.Tpo $(DEPDIR)/omhttp_la-omhttp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omhttp.c' object='omhttp_la-omhttp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omhttp_la-omhttp.lo `test -f 'omhttp.c' || echo '$(srcdir)/'`omhttp.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omhttp_la-omhttp.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omhttp_la-omhttp.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omhttp/omhttp.c b/contrib/omhttp/omhttp.c new file mode 100644 index 0000000..a2a8111 --- /dev/null +++ b/contrib/omhttp/omhttp.c @@ -0,0 +1,2212 @@ +/* omhttp.c + * This is an http output module based on omelasticsearch + * + * NOTE: read comments in module-template.h for more specifics! + * + * Copyright 2011 Nathan Scott. + * Copyright 2009-2018 Rainer Gerhards and Adiscon GmbH. + * Copyright 2018 Christian Tramnitz + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <memory.h> +#include <string.h> +#include <curl/curl.h> +#include <curl/easy.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(__FreeBSD__) +#include <unistd.h> +#endif +#include <json.h> +#include <zlib.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "unicode-helper.h" +#include "obj-types.h" +#include "ratelimit.h" +#include "ruleset.h" +#include "statsobj.h" + +#ifndef O_LARGEFILE +# define O_LARGEFILE 0 +#endif + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omhttp") + +/* internal structures */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(prop) +DEFobjCurrIf(ruleset) +DEFobjCurrIf(statsobj) + +statsobj_t *httpStats; +STATSCOUNTER_DEF(ctrMessagesSubmitted, mutCtrMessagesSubmitted); // Number of message submitted to module +STATSCOUNTER_DEF(ctrMessagesSuccess, mutCtrMessagesSuccess); // Number of messages successfully sent +STATSCOUNTER_DEF(ctrMessagesFail, mutCtrMessagesFail); // Number of messages that failed to send +STATSCOUNTER_DEF(ctrMessagesRetry, mutCtrMessagesRetry); // Number of messages requeued for retry +STATSCOUNTER_DEF(ctrHttpRequestCount, mutCtrHttpRequestCount); // Number of attempted HTTP requests +STATSCOUNTER_DEF(ctrHttpRequestSuccess, mutCtrHttpRequestSuccess); // Number of successful HTTP requests +STATSCOUNTER_DEF(ctrHttpRequestFail, mutCtrHttpRequestFail); // Number of failed HTTP req, 4XX+ are NOT failures +STATSCOUNTER_DEF(ctrHttpStatusSuccess, mutCtrHttpStatusSuccess); // Number of requests returning 1XX/2XX status +STATSCOUNTER_DEF(ctrHttpStatusFail, mutCtrHttpStatusFail); // Number of requests returning 300+ status + +static prop_t *pInputName = NULL; + +#define WRKR_DATA_TYPE_ES 0xBADF0001 + +#define HTTP_HEADER_CONTENT_JSON "Content-Type: application/json; charset=utf-8" +#define HTTP_HEADER_CONTENT_TEXT "Content-Type: text/plain" +#define HTTP_HEADER_CONTENT_KAFKA "Content-Type: application/vnd.kafka.v1+json" +#define HTTP_HEADER_ENCODING_GZIP "Content-Encoding: gzip" +#define HTTP_HEADER_EXPECT_EMPTY "Expect:" + +#define VALID_BATCH_FORMATS "newline jsonarray kafkarest lokirest" +typedef enum batchFormat_e { + FMT_NEWLINE, + FMT_JSONARRAY, + FMT_KAFKAREST, + FMT_LOKIREST +} batchFormat_t; + +/* REST API uses this URL: + * https://<hostName>:<restPort>/restPath +*/ +typedef struct curl_slist HEADER; +typedef struct instanceConf_s { + int defaultPort; + int fdErrFile; /* error file fd or -1 if not open */ + pthread_mutex_t mutErrFile; + uchar **serverBaseUrls; + int numServers; + long healthCheckTimeout; + uchar *uid; + uchar *pwd; + uchar *authBuf; + uchar *httpcontenttype; + uchar *headerContentTypeBuf; + uchar *httpheaderkey; + uchar *httpheadervalue; + uchar *headerBuf; + uchar **httpHeaders; + int nHttpHeaders; + uchar *restPath; + uchar *checkPath; + uchar *tplName; + uchar *errorFile; + sbool batchMode; + uchar *batchFormatName; + batchFormat_t batchFormat; + sbool bFreeBatchFormatName; + sbool dynRestPath; + size_t maxBatchBytes; + size_t maxBatchSize; + sbool compress; + int compressionLevel; /* Compression level for zlib, default=-1, fastest=1, best=9, none=0*/ + sbool useHttps; + sbool allowUnsignedCerts; + sbool skipVerifyHost; + uchar *caCertFile; + uchar *myCertFile; + uchar *myPrivKeyFile; + sbool reloadOnHup; + sbool retryFailures; + unsigned int ratelimitInterval; + unsigned int ratelimitBurst; + /* for retries */ + ratelimit_t *ratelimiter; + uchar *retryRulesetName; + ruleset_t *retryRuleset; + struct instanceConf_s *next; +} instanceData; + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ + instanceConf_t *root, *tail; +}; +static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ + +typedef struct wrkrInstanceData { + PTR_ASSERT_DEF + instanceData *pData; + int serverIndex; + int replyLen; + char *reply; + long httpStatusCode; /* http status code of response */ + CURL *curlCheckConnHandle; /* libcurl session handle for checking the server connection */ + CURL *curlPostHandle; /* libcurl session handle for posting data to the server */ + HEADER *curlHeader; /* json POST request info */ + uchar *restURL; /* last used URL for error reporting */ + sbool bzInitDone; + z_stream zstrm; /* zip stream to use for gzip http compression */ + struct { + uchar **data; /* array of strings, this will be batched up lazily */ + uchar *restPath; /* Helper for restpath in batch mode */ + size_t sizeBytes; /* total length of this batch in bytes */ + size_t nmemb; /* number of messages in batch (for statistics counting) */ + + } batch; + struct { + uchar *buf; + size_t curLen; + size_t len; + } compressCtx; +} wrkrInstanceData_t; + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "server", eCmdHdlrArray, 0 }, + { "serverport", eCmdHdlrInt, 0 }, + { "healthchecktimeout", eCmdHdlrInt, 0 }, + { "httpcontenttype", eCmdHdlrGetWord, 0 }, + { "httpheaderkey", eCmdHdlrGetWord, 0 }, + { "httpheadervalue", eCmdHdlrString, 0 }, + { "httpheaders", eCmdHdlrArray, 0 }, + { "uid", eCmdHdlrGetWord, 0 }, + { "pwd", eCmdHdlrGetWord, 0 }, + { "restpath", eCmdHdlrGetWord, 0 }, + { "checkpath", eCmdHdlrGetWord, 0 }, + { "dynrestpath", eCmdHdlrBinary, 0 }, + { "batch", eCmdHdlrBinary, 0 }, + { "batch.format", eCmdHdlrGetWord, 0 }, + { "batch.maxbytes", eCmdHdlrSize, 0 }, + { "batch.maxsize", eCmdHdlrSize, 0 }, + { "compress", eCmdHdlrBinary, 0 }, + { "compress.level", eCmdHdlrInt, 0 }, + { "usehttps", eCmdHdlrBinary, 0 }, + { "errorfile", eCmdHdlrGetWord, 0 }, + { "template", eCmdHdlrGetWord, 0 }, + { "allowunsignedcerts", eCmdHdlrBinary, 0 }, + { "skipverifyhost", eCmdHdlrBinary, 0 }, + { "tls.cacert", eCmdHdlrString, 0 }, + { "tls.mycert", eCmdHdlrString, 0 }, + { "tls.myprivkey", eCmdHdlrString, 0 }, + { "reloadonhup", eCmdHdlrBinary, 0 }, + { "retry", eCmdHdlrBinary, 0 }, + { "retry.ruleset", eCmdHdlrString, 0 }, + { "ratelimit.interval", eCmdHdlrInt, 0 }, + { "ratelimit.burst", eCmdHdlrInt, 0 }, +}; +static struct cnfparamblk actpblk = + { CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr + }; + +static rsRetVal curlSetup(wrkrInstanceData_t *pWrkrData); +static void curlCleanup(wrkrInstanceData_t *pWrkrData); +static void curlCheckConnSetup(wrkrInstanceData_t *const pWrkrData); + +/* compressCtx functions */ +static void ATTR_NONNULL() +initCompressCtx(wrkrInstanceData_t *pWrkrData); + +static void ATTR_NONNULL() +freeCompressCtx(wrkrInstanceData_t *pWrkrData); + +static rsRetVal ATTR_NONNULL() +resetCompressCtx(wrkrInstanceData_t *pWrkrData, size_t len); + +static rsRetVal ATTR_NONNULL() +growCompressCtx(wrkrInstanceData_t *pWrkrData, size_t newLen); + +static rsRetVal ATTR_NONNULL() +appendCompressCtx(wrkrInstanceData_t *pWrkrData, uchar *srcBuf, size_t srcLen); + +BEGINcreateInstance +CODESTARTcreateInstance + pData->fdErrFile = -1; + pthread_mutex_init(&pData->mutErrFile, NULL); + pData->caCertFile = NULL; + pData->myCertFile = NULL; + pData->myPrivKeyFile = NULL; + pData->ratelimiter = NULL; + pData->retryRulesetName = NULL; + pData->retryRuleset = NULL; +ENDcreateInstance + +BEGINcreateWrkrInstance +uchar **batchData; +CODESTARTcreateWrkrInstance + PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); + pWrkrData->curlHeader = NULL; + pWrkrData->curlPostHandle = NULL; + pWrkrData->curlCheckConnHandle = NULL; + pWrkrData->serverIndex = 0; + pWrkrData->httpStatusCode = 0; + pWrkrData->restURL = NULL; + pWrkrData->bzInitDone = 0; + if(pData->batchMode) { + pWrkrData->batch.nmemb = 0; + pWrkrData->batch.sizeBytes = 0; + batchData = (uchar **) malloc(pData->maxBatchSize * sizeof(uchar *)); + if (batchData == NULL) { + LogError(0, RS_RET_OUT_OF_MEMORY, + "omhttp: cannot allocate memory for batch queue turning off batch mode\n"); + pData->batchMode = 0; /* at least it works */ + } else { + pWrkrData->batch.data = batchData; + pWrkrData->batch.restPath = NULL; + } + } + initCompressCtx(pWrkrData); + iRet = curlSetup(pWrkrData); +ENDcreateWrkrInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURERepeatedMsgReduction) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +BEGINfreeInstance + int i; +CODESTARTfreeInstance + if(pData->fdErrFile != -1) + close(pData->fdErrFile); + pthread_mutex_destroy(&pData->mutErrFile); + for(i = 0 ; i < pData->numServers ; ++i) + free(pData->serverBaseUrls[i]); + free(pData->serverBaseUrls); + free(pData->uid); + free(pData->httpcontenttype); + free(pData->headerContentTypeBuf); + free(pData->httpheaderkey); + free(pData->httpheadervalue); + for(i = 0 ; i < pData->nHttpHeaders ; ++i) { + free((void*) pData->httpHeaders[i]); + } + free(pData->httpHeaders); + pData->nHttpHeaders = 0; + free(pData->pwd); + free(pData->authBuf); + free(pData->headerBuf); + free(pData->restPath); + free(pData->checkPath); + free(pData->tplName); + free(pData->errorFile); + free(pData->caCertFile); + free(pData->myCertFile); + free(pData->myPrivKeyFile); + free(pData->retryRulesetName); + if (pData->ratelimiter != NULL) + ratelimitDestruct(pData->ratelimiter); + if (pData->bFreeBatchFormatName) + free(pData->batchFormatName); +ENDfreeInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance + curlCleanup(pWrkrData); + + free(pWrkrData->restURL); + pWrkrData->restURL = NULL; + + free(pWrkrData->batch.data); + pWrkrData->batch.data = NULL; + + if (pWrkrData->batch.restPath != NULL) { + free(pWrkrData->batch.restPath); + pWrkrData->batch.restPath = NULL; + } + + if (pWrkrData->bzInitDone) + deflateEnd(&pWrkrData->zstrm); + freeCompressCtx(pWrkrData); + +ENDfreeWrkrInstance + +BEGINdbgPrintInstInfo + int i; +CODESTARTdbgPrintInstInfo + dbgprintf("omhttp\n"); + dbgprintf("\ttemplate='%s'\n", pData->tplName); + dbgprintf("\tnumServers=%d\n", pData->numServers); + dbgprintf("\thealthCheckTimeout=%lu\n", pData->healthCheckTimeout); + dbgprintf("\tserverBaseUrls="); + for(i = 0 ; i < pData->numServers ; ++i) + dbgprintf("%c'%s'", i == 0 ? '[' : ' ', pData->serverBaseUrls[i]); + dbgprintf("]\n"); + dbgprintf("\tdefaultPort=%d\n", pData->defaultPort); + dbgprintf("\tuid='%s'\n", pData->uid == NULL ? (uchar*)"(not configured)" : pData->uid); + dbgprintf("\thttpcontenttype='%s'\n", pData->httpcontenttype == NULL ? + (uchar*)"(not configured)" : pData->httpcontenttype); + dbgprintf("\thttpheaderkey='%s'\n", pData->httpheaderkey == NULL ? + (uchar*)"(not configured)" : pData->httpheaderkey); + dbgprintf("\thttpheadervalue='%s'\n", pData->httpheadervalue == NULL ? + (uchar*)"(not configured)" : pData->httpheadervalue); + dbgprintf("\thttpHeaders=["); + for(i = 0 ; i < pData->nHttpHeaders ; ++i) + dbgprintf("\t%s\n",pData->httpHeaders[i]); + dbgprintf("\t]\n"); + dbgprintf("\tpwd=(%sconfigured)\n", pData->pwd == NULL ? "not " : ""); + dbgprintf("\trest path='%s'\n", pData->restPath); + dbgprintf("\tcheck path='%s'\n", pData->checkPath); + dbgprintf("\tdynamic rest path=%d\n", pData->dynRestPath); + dbgprintf("\tuse https=%d\n", pData->useHttps); + dbgprintf("\tbatch=%d\n", pData->batchMode); + dbgprintf("\tbatch.format='%s'\n", pData->batchFormatName); + dbgprintf("\tbatch.maxbytes=%zu\n", pData->maxBatchBytes); + dbgprintf("\tbatch.maxsize=%zu\n", pData->maxBatchSize); + dbgprintf("\tcompress=%d\n", pData->compress); + dbgprintf("\tcompress.level=%d\n", pData->compressionLevel); + dbgprintf("\tallowUnsignedCerts=%d\n", pData->allowUnsignedCerts); + dbgprintf("\tskipVerifyHost=%d\n", pData->skipVerifyHost); + dbgprintf("\terrorfile='%s'\n", pData->errorFile == NULL ? + (uchar*)"(not configured)" : pData->errorFile); + dbgprintf("\ttls.cacert='%s'\n", pData->caCertFile); + dbgprintf("\ttls.mycert='%s'\n", pData->myCertFile); + dbgprintf("\ttls.myprivkey='%s'\n", pData->myPrivKeyFile); + dbgprintf("\treloadonhup='%d'\n", pData->reloadOnHup); + dbgprintf("\tretry='%d'\n", pData->retryFailures); + dbgprintf("\tretry.ruleset='%s'\n", pData->retryRulesetName); + dbgprintf("\tratelimit.interval='%u'\n", pData->ratelimitInterval); + dbgprintf("\tratelimit.burst='%u'\n", pData->ratelimitBurst); +ENDdbgPrintInstInfo + + +/* http POST result string ... useful for debugging */ +static size_t +curlResult(void *ptr, size_t size, size_t nmemb, void *userdata) +{ + char *p = (char *)ptr; + wrkrInstanceData_t *pWrkrData = (wrkrInstanceData_t*) userdata; + char *buf; + size_t newlen; + PTR_ASSERT_CHK(pWrkrData, WRKR_DATA_TYPE_ES); + newlen = pWrkrData->replyLen + size*nmemb; + if((buf = realloc(pWrkrData->reply, newlen + 1)) == NULL) { + LogError(errno, RS_RET_ERR, "omhttp: realloc failed in curlResult"); + return 0; /* abort due to failure */ + } + memcpy(buf+pWrkrData->replyLen, p, size*nmemb); + pWrkrData->replyLen = newlen; + pWrkrData->reply = buf; + return size*nmemb; +} + +/* Build basic URL part, which includes hostname and port as follows: + * http://hostname:port/ based on a server param + * Newly creates a cstr for this purpose. + * Note: serverParam MUST NOT end in '/' (caller must strip if it exists) + */ +static rsRetVal +computeBaseUrl(const char*const serverParam, + const int defaultPort, + const sbool useHttps, + uchar **baseUrl) +{ +# define SCHEME_HTTPS "https://" +# define SCHEME_HTTP "http://" + + char portBuf[64]; + int r = 0; + const char *host = serverParam; + DEFiRet; + + assert(serverParam[strlen(serverParam)-1] != '/'); + + es_str_t *urlBuf = es_newStr(256); + if (urlBuf == NULL) { + LogError(0, RS_RET_OUT_OF_MEMORY, + "omhttp: failed to allocate es_str urlBuf in computeBaseUrl"); + ABORT_FINALIZE(RS_RET_ERR); + } + + /* Find where the hostname/ip of the server starts. If the scheme is not specified + * in the uri, start the buffer with a scheme corresponding to the useHttps parameter. + */ + if (strcasestr(serverParam, SCHEME_HTTP)) + host = serverParam + strlen(SCHEME_HTTP); + else if (strcasestr(serverParam, SCHEME_HTTPS)) + host = serverParam + strlen(SCHEME_HTTPS); + else + r = useHttps ? es_addBuf(&urlBuf, SCHEME_HTTPS, sizeof(SCHEME_HTTPS)-1) : + es_addBuf(&urlBuf, SCHEME_HTTP, sizeof(SCHEME_HTTP)-1); + + if (r == 0) r = es_addBuf(&urlBuf, (char *)serverParam, strlen(serverParam)); + if (r == 0 && !strchr(host, ':')) { + snprintf(portBuf, sizeof(portBuf), ":%d", defaultPort); + r = es_addBuf(&urlBuf, portBuf, strlen(portBuf)); + } + if (r == 0) r = es_addChar(&urlBuf, '/'); + if (r == 0) *baseUrl = (uchar*) es_str2cstr(urlBuf, NULL); + + if (r != 0 || baseUrl == NULL) { + LogError(0, RS_RET_ERR, + "omhttp: error occurred computing baseUrl from server %s", serverParam); + ABORT_FINALIZE(RS_RET_ERR); + } +finalize_it: + if (urlBuf) { + es_deleteStr(urlBuf); + } + RETiRet; +} + +static inline void +incrementServerIndex(wrkrInstanceData_t *pWrkrData) +{ + pWrkrData->serverIndex = (pWrkrData->serverIndex + 1) % pWrkrData->pData->numServers; +} + + +/* checks if connection to ES can be established; also iterates over + * potential servers to support high availability (HA) feature. If it + * needs to switch server, will record new one in curl handle. + */ +static rsRetVal ATTR_NONNULL() +checkConn(wrkrInstanceData_t *const pWrkrData) +{ + CURL *curl; + CURLcode res; + es_str_t *urlBuf = NULL; + char* healthUrl; + char* serverUrl; + char* checkPath; + int i; + int r; + DEFiRet; + + if (pWrkrData->pData->checkPath == NULL) { + DBGPRINTF("omhttp: checkConn no health check uri configured skipping it\n"); + FINALIZE; + } + + pWrkrData->reply = NULL; + pWrkrData->replyLen = 0; + curl = pWrkrData->curlCheckConnHandle; + urlBuf = es_newStr(256); + if (urlBuf == NULL) { + LogError(0, RS_RET_OUT_OF_MEMORY, + "omhttp: unable to allocate buffer for health check uri."); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + + for(i = 0; i < pWrkrData->pData->numServers; ++i) { + serverUrl = (char*) pWrkrData->pData->serverBaseUrls[pWrkrData->serverIndex]; + checkPath = (char*) pWrkrData->pData->checkPath; + + es_emptyStr(urlBuf); + r = es_addBuf(&urlBuf, serverUrl, strlen(serverUrl)); + if(r == 0 && checkPath != NULL) + r = es_addBuf(&urlBuf, checkPath, strlen(checkPath)); + if(r == 0) + healthUrl = es_str2cstr(urlBuf, NULL); + if(r != 0 || healthUrl == NULL) { + LogError(0, RS_RET_OUT_OF_MEMORY, + "omhttp: unable to allocate buffer for health check uri."); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } + + curlCheckConnSetup(pWrkrData); + curl_easy_setopt(curl, CURLOPT_URL, healthUrl); + res = curl_easy_perform(curl); + free(healthUrl); + + if (res == CURLE_OK) { + DBGPRINTF("omhttp: checkConn %s completed with success " + "on attempt %d\n", serverUrl, i); + ABORT_FINALIZE(RS_RET_OK); + } + + DBGPRINTF("omhttp: checkConn %s failed on attempt %d: %s\n", + serverUrl, i, curl_easy_strerror(res)); + incrementServerIndex(pWrkrData); + } + + LogMsg(0, RS_RET_SUSPENDED, LOG_WARNING, + "omhttp: checkConn failed after %d attempts.", i); + ABORT_FINALIZE(RS_RET_SUSPENDED); + +finalize_it: + if(urlBuf != NULL) + es_deleteStr(urlBuf); + + free(pWrkrData->reply); + pWrkrData->reply = NULL; /* don't leave dangling pointer */ + RETiRet; +} + + +BEGINtryResume +CODESTARTtryResume + DBGPRINTF("omhttp: tryResume called\n"); + iRet = checkConn(pWrkrData); +ENDtryResume + + +/* get the current index and type for this message */ +static void ATTR_NONNULL(1) +getRestPath(const instanceData *const pData, uchar **const tpls, + uchar **const restPath) +{ + *restPath = pData->restPath; + if(tpls == NULL) { + goto done; + } + + int iNumTpls = 1; + if(pData->dynRestPath) { + *restPath = tpls[iNumTpls]; + ++iNumTpls; + } + +done: + assert(restPath != NULL); + return; +} + + +static rsRetVal ATTR_NONNULL(1) +setPostURL(wrkrInstanceData_t *const pWrkrData, uchar **const tpls) +{ + uchar *restPath; + char* baseUrl; + es_str_t *url; + int r; + DEFiRet; + instanceData *const pData = pWrkrData->pData; + + baseUrl = (char*)pData->serverBaseUrls[pWrkrData->serverIndex]; + url = es_newStrFromCStr(baseUrl, strlen(baseUrl)); + if (url == NULL) { + LogError(0, RS_RET_OUT_OF_MEMORY, + "omhttp: error allocating new estr for POST url."); + ABORT_FINALIZE(RS_RET_ERR); + } + + if (pWrkrData->batch.restPath != NULL) { + /* get from batch if set! */ + restPath = pWrkrData->batch.restPath; + } else { + getRestPath(pData, tpls, &restPath); + } + + r = 0; + if (restPath != NULL) + r = es_addBuf(&url, (char*)restPath, ustrlen(restPath)); + + if(r != 0) { + LogError(0, RS_RET_ERR, "omhttp: failure in creating restURL, " + "error code: %d", r); + ABORT_FINALIZE(RS_RET_ERR); + } + + if(pWrkrData->restURL != NULL) + free(pWrkrData->restURL); + + pWrkrData->restURL = (uchar*)es_str2cstr(url, NULL); + curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_URL, pWrkrData->restURL); + DBGPRINTF("omhttp: using REST URL: '%s'\n", pWrkrData->restURL); + +finalize_it: + if (url != NULL) + es_deleteStr(url); + RETiRet; +} + +/* + * Dumps entire bulk request and response in error log + * { + * "request": { + * "url": "https://url.com:443/path", + * "postdata": "mypayload" } + * "response" : { + * "status": 400, + * "response": "error string" } + * } + */ +static rsRetVal +renderJsonErrorMessage(wrkrInstanceData_t *pWrkrData, uchar *reqmsg, char **rendered) +{ + DEFiRet; + fjson_object *req = NULL; + fjson_object *res = NULL; + fjson_object *errRoot = NULL; + + if ((req = fjson_object_new_object()) == NULL) + ABORT_FINALIZE(RS_RET_ERR); + fjson_object_object_add(req, "url", fjson_object_new_string((char *)pWrkrData->restURL)); + fjson_object_object_add(req, "postdata", fjson_object_new_string((char *)reqmsg)); + + if ((res = fjson_object_new_object()) == NULL) { + fjson_object_put(req); // cleanup request object + ABORT_FINALIZE(RS_RET_ERR); + } + + #define ERR_MSG_NULL "NULL: curl request failed or no response" + fjson_object_object_add(res, "status", fjson_object_new_int(pWrkrData->httpStatusCode)); + if (pWrkrData->reply == NULL) { + fjson_object_object_add(res, "message", + fjson_object_new_string_len(ERR_MSG_NULL, strlen(ERR_MSG_NULL))); + } else { + fjson_object_object_add(res, "message", + fjson_object_new_string_len(pWrkrData->reply, pWrkrData->replyLen)); + } + + if ((errRoot = fjson_object_new_object()) == NULL) { + fjson_object_put(req); // cleanup request object + fjson_object_put(res); // cleanup response object + ABORT_FINALIZE(RS_RET_ERR); + } + + fjson_object_object_add(errRoot, "request", req); + fjson_object_object_add(errRoot, "response", res); + + *rendered = strdup((char *) fjson_object_to_json_string(errRoot)); + +finalize_it: + if (errRoot != NULL) + fjson_object_put(errRoot); + + RETiRet; +} + +/* write data error request/replies to separate error file + * Note: we open the file but never close it before exit. If it + * needs to be closed, HUP must be sent. + */ +static rsRetVal ATTR_NONNULL() +writeDataError(wrkrInstanceData_t *const pWrkrData, + instanceData *const pData, uchar *const reqmsg) +{ + char *rendered = NULL; + size_t toWrite; + ssize_t wrRet; + sbool bMutLocked = 0; + + DEFiRet; + + if(pData->errorFile == NULL) { + DBGPRINTF("omhttp: no local error logger defined - " + "ignoring REST error information\n"); + FINALIZE; + } + + pthread_mutex_lock(&pData->mutErrFile); + bMutLocked = 1; + + CHKiRet(renderJsonErrorMessage(pWrkrData, reqmsg, &rendered)); + + if(pData->fdErrFile == -1) { + pData->fdErrFile = open((char*)pData->errorFile, + O_WRONLY|O_CREAT|O_APPEND|O_LARGEFILE|O_CLOEXEC, + S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); + if(pData->fdErrFile == -1) { + LogError(errno, RS_RET_ERR, "omhttp: error opening error file %s", + pData->errorFile); + ABORT_FINALIZE(RS_RET_ERR); + } + } + + /* we do not do real error-handling on the err file, as this finally complicates + * things way to much. + */ + DBGPRINTF("omhttp: error record: '%s'\n", rendered); + toWrite = strlen(rendered) + 1; + /* Note: we overwrite the '\0' terminator with '\n' -- so we avoid + * caling malloc() -- write() does NOT need '\0'! + */ + rendered[toWrite-1] = '\n'; /* NO LONGER A STRING! */ + wrRet = write(pData->fdErrFile, rendered, toWrite); + if(wrRet != (ssize_t) toWrite) { + LogError(errno, RS_RET_IO_ERROR, + "omhttp: error writing error file %s, write returned %lld", + pData->errorFile, (long long) wrRet); + } + +finalize_it: + if(bMutLocked) + pthread_mutex_unlock(&pData->mutErrFile); + free(rendered); + RETiRet; +} + +static rsRetVal +queueBatchOnRetryRuleset(wrkrInstanceData_t *const pWrkrData, instanceData *const pData) +{ + uchar *msgData; + smsg_t *pMsg; + DEFiRet; + + if (pData->retryRuleset == NULL) { + LogError(0, RS_RET_ERR, "omhttp: queueBatchOnRetryRuleset invalid call with a NULL retryRuleset"); + ABORT_FINALIZE(RS_RET_ERR); + } + + for (size_t i = 0; i < pWrkrData->batch.nmemb; i++) { + msgData = pWrkrData->batch.data[i]; + DBGPRINTF("omhttp: queueBatchOnRetryRuleset putting message '%s' into retry ruleset '%s'\n", + msgData, pData->retryRulesetName); + + // Construct the message object + CHKiRet(msgConstruct(&pMsg)); + CHKiRet(MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY)); + MsgSetInputName(pMsg, pInputName); + MsgSetRawMsg(pMsg, (const char *)msgData, ustrlen(msgData)); + MsgSetMSGoffs(pMsg, 0); // No header + MsgSetTAG(pMsg, (const uchar *)"omhttp-retry", 12); + + // And place it on the retry ruleset + MsgSetRuleset(pMsg, pData->retryRuleset); + ratelimitAddMsg(pData->ratelimiter, NULL, pMsg); + + // Count here in case not entire batch succeeds + STATSCOUNTER_INC(ctrMessagesRetry, mutCtrMessagesRetry); + } +finalize_it: + RETiRet; +} + +static rsRetVal +checkResult(wrkrInstanceData_t *pWrkrData, uchar *reqmsg) +{ + instanceData *pData; + long statusCode; + size_t numMessages; + DEFiRet; + + pData = pWrkrData->pData; + statusCode = pWrkrData->httpStatusCode; + + if (pData->batchMode) { + numMessages = pWrkrData->batch.nmemb; + } else { + numMessages = 1; + } + + // 500+ errors return RS_RET_SUSPENDED if NOT batchMode and should be retried + // status 0 is the default and the request failed for some reason, retry this too + // 400-499 are malformed input and should not be retried just logged instead + if (statusCode == 0) { + // request failed, suspend or retry + STATSCOUNTER_ADD(ctrMessagesFail, mutCtrMessagesFail, numMessages); + iRet = RS_RET_SUSPENDED; + } else if (statusCode >= 500) { + // server error, suspend or retry + STATSCOUNTER_INC(ctrHttpStatusFail, mutCtrHttpStatusFail); + STATSCOUNTER_ADD(ctrMessagesFail, mutCtrMessagesFail, numMessages); + iRet = RS_RET_SUSPENDED; + } else if (statusCode >= 300) { + // redirection or client error, NO suspend nor retry + STATSCOUNTER_INC(ctrHttpStatusFail, mutCtrHttpStatusFail); + STATSCOUNTER_ADD(ctrMessagesFail, mutCtrMessagesFail, numMessages); + iRet = RS_RET_DATAFAIL; + } else { + // success, normal state + // includes 2XX (success like 200-OK) + // includes 1XX (informational like 100-Continue) + STATSCOUNTER_INC(ctrHttpStatusSuccess, mutCtrHttpStatusSuccess); + STATSCOUNTER_ADD(ctrMessagesSuccess, mutCtrMessagesSuccess, numMessages); + iRet = RS_RET_OK; + } + + if (iRet != RS_RET_OK) { + LogMsg(0, iRet, LOG_ERR, "omhttp: checkResult error http status code: %ld reply: %s", + statusCode, pWrkrData->reply != NULL ? pWrkrData->reply : "NULL"); + + writeDataError(pWrkrData, pWrkrData->pData, reqmsg); + + if (iRet == RS_RET_DATAFAIL) + ABORT_FINALIZE(iRet); + + if (pData->batchMode && pData->maxBatchSize > 1) { + // Write each message back to retry ruleset if configured + if (pData->retryFailures && pData->retryRuleset != NULL) { + // Retry stats counted inside this function call + iRet = queueBatchOnRetryRuleset(pWrkrData, pData); + if (iRet != RS_RET_OK) { + LogMsg(0, iRet, LOG_ERR, + "omhttp: checkResult error while queueing to retry ruleset" + "some messages may be lost"); + } + } + iRet = RS_RET_OK; // We've done all we can tell rsyslog to carry on + } + } + +finalize_it: + RETiRet; +} + +/* Compress a buffer before sending using zlib. Based on code from tools/omfwd.c + * Initialize the zstrm object for gzip compression, using this init function. + * deflateInit2(z_stream strm, int level, int method, + * int windowBits, int memLevel, int strategy); + * strm: the zlib stream held in pWrkrData + * level: the compression level held in pData + * method: the operation constant Z_DEFLATED + * windowBits: the size of the compression window 15 = log_2(32768) + * to configure as gzip add 16 to windowBits (w | 16) for final value 31 + * memLevel: the memory optimization level 8 is default) + * strategy: using Z_DEFAULT_STRATEGY is default + */ +static rsRetVal +compressHttpPayload(wrkrInstanceData_t *pWrkrData, uchar *message, unsigned len) +{ + int zRet; + unsigned outavail; + uchar zipBuf[32*1024]; + + DEFiRet; + + if (!pWrkrData->bzInitDone) { + pWrkrData->zstrm.zalloc = Z_NULL; + pWrkrData->zstrm.zfree = Z_NULL; + pWrkrData->zstrm.opaque = Z_NULL; + zRet = deflateInit2(&pWrkrData->zstrm, pWrkrData->pData->compressionLevel, + Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY); + if (zRet != Z_OK) { + DBGPRINTF("omhttp: compressHttpPayload error %d returned from zlib/deflateInit2()\n", zRet); + ABORT_FINALIZE(RS_RET_ZLIB_ERR); + } + pWrkrData->bzInitDone = 1; + } + + CHKiRet(resetCompressCtx(pWrkrData, len)); + + /* now doing the compression */ + pWrkrData->zstrm.next_in = (Bytef*) message; + pWrkrData->zstrm.avail_in = len; + /* run deflate() on buffer until everything has been compressed */ + do { + DBGPRINTF("omhttp: compressHttpPayload in deflate() loop, avail_in %d, total_in %ld\n", + pWrkrData->zstrm.avail_in, pWrkrData->zstrm.total_in); + pWrkrData->zstrm.avail_out = sizeof(zipBuf); + pWrkrData->zstrm.next_out = zipBuf; + + zRet = deflate(&pWrkrData->zstrm, Z_NO_FLUSH); + DBGPRINTF("omhttp: compressHttpPayload after deflate, ret %d, avail_out %d\n", + zRet, pWrkrData->zstrm.avail_out); + if (zRet != Z_OK) + ABORT_FINALIZE(RS_RET_ZLIB_ERR); + outavail = sizeof(zipBuf) - pWrkrData->zstrm.avail_out; + if (outavail != 0) + CHKiRet(appendCompressCtx(pWrkrData, zipBuf, outavail)); + + } while (pWrkrData->zstrm.avail_out == 0); + + /* run deflate again with Z_FINISH with no new input */ + pWrkrData->zstrm.avail_in = 0; + do { + pWrkrData->zstrm.avail_out = sizeof(zipBuf); + pWrkrData->zstrm.next_out = zipBuf; + deflate(&pWrkrData->zstrm, Z_FINISH); /* returns Z_STREAM_END == 1 */ + outavail = sizeof(zipBuf) - pWrkrData->zstrm.avail_out; + if (outavail != 0) + CHKiRet(appendCompressCtx(pWrkrData, zipBuf, outavail)); + + } while (pWrkrData->zstrm.avail_out == 0); + +finalize_it: + if (pWrkrData->bzInitDone) + deflateEnd(&pWrkrData->zstrm); + pWrkrData->bzInitDone = 0; + RETiRet; + +} + +static void ATTR_NONNULL() +initCompressCtx(wrkrInstanceData_t *pWrkrData) +{ + pWrkrData->compressCtx.buf = NULL; + pWrkrData->compressCtx.curLen = 0; + pWrkrData->compressCtx.len = 0; +} + +static void ATTR_NONNULL() +freeCompressCtx(wrkrInstanceData_t *pWrkrData) +{ + if (pWrkrData->compressCtx.buf != NULL) { + free(pWrkrData->compressCtx.buf); + pWrkrData->compressCtx.buf = NULL; + } +} + + +static rsRetVal ATTR_NONNULL() +resetCompressCtx(wrkrInstanceData_t *pWrkrData, size_t len) +{ + DEFiRet; + pWrkrData->compressCtx.curLen = 0; + pWrkrData->compressCtx.len = len; + CHKiRet(growCompressCtx(pWrkrData, len)); + +finalize_it: + if (iRet != RS_RET_OK) + freeCompressCtx(pWrkrData); + RETiRet; +} + +static rsRetVal ATTR_NONNULL() +growCompressCtx(wrkrInstanceData_t *pWrkrData, size_t newLen) +{ + DEFiRet; + if (pWrkrData->compressCtx.buf == NULL) { + CHKmalloc(pWrkrData->compressCtx.buf = (uchar *)malloc(sizeof(uchar)*newLen)); + } else { + uchar *const newbuf = (uchar *)realloc(pWrkrData->compressCtx.buf, sizeof(uchar)*newLen); + CHKmalloc(newbuf); + pWrkrData->compressCtx.buf = newbuf; + } + pWrkrData->compressCtx.len = newLen; +finalize_it: + RETiRet; + +} + +static rsRetVal ATTR_NONNULL() +appendCompressCtx(wrkrInstanceData_t *pWrkrData, uchar *srcBuf, size_t srcLen) +{ + size_t newLen; + DEFiRet; + newLen = pWrkrData->compressCtx.curLen + srcLen; + if (newLen > pWrkrData->compressCtx.len) + CHKiRet(growCompressCtx(pWrkrData, newLen)); + + memcpy(pWrkrData->compressCtx.buf + pWrkrData->compressCtx.curLen, + srcBuf, srcLen); + pWrkrData->compressCtx.curLen = newLen; +finalize_it: + if (iRet != RS_RET_OK) + freeCompressCtx(pWrkrData); + RETiRet; +} + +/* Some duplicate code to curlSetup, but we need to add the gzip content-encoding + * header at runtime, and if the compression fails, we do not want to send it. + * Additionally, the curlCheckConnHandle should not be configured with a gzip header. + */ +static rsRetVal ATTR_NONNULL() +buildCurlHeaders(wrkrInstanceData_t *pWrkrData, sbool contentEncodeGzip) +{ + struct curl_slist *slist = NULL; + + DEFiRet; + + if (pWrkrData->pData->httpcontenttype != NULL) { + // If content type specified use it, otherwise use a sane default + slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerContentTypeBuf); + } else { + if (pWrkrData->pData->batchMode) { + // If in batch mode, use the approprate content type header for the format, + // defaulting to text/plain with newline + switch (pWrkrData->pData->batchFormat) { + case FMT_JSONARRAY: + slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); + break; + case FMT_KAFKAREST: + slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_KAFKA); + break; + case FMT_NEWLINE: + slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_TEXT); + break; + case FMT_LOKIREST: + slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); + break; + default: + slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_TEXT); + } + } else { + // Otherwise non batch, presume most users are sending JSON + slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); + } + } + + CHKmalloc(slist); + + // Configured headers.. + if (pWrkrData->pData->headerBuf != NULL) { + slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerBuf); + CHKmalloc(slist); + } + + for (int k = 0 ; k < pWrkrData->pData->nHttpHeaders; k++) { + slist = curl_slist_append(slist, (char *)pWrkrData->pData->httpHeaders[k]); + CHKmalloc(slist); + } + + // When sending more than 1Kb, libcurl automatically sends an Except: 100-Continue header + // and will wait 1s for a response, could make this configurable but for now disable + slist = curl_slist_append(slist, HTTP_HEADER_EXPECT_EMPTY); + CHKmalloc(slist); + + if (contentEncodeGzip) { + slist = curl_slist_append(slist, HTTP_HEADER_ENCODING_GZIP); + CHKmalloc(slist); + } + + if (pWrkrData->curlHeader != NULL) + curl_slist_free_all(pWrkrData->curlHeader); + + pWrkrData->curlHeader = slist; + +finalize_it: + if (iRet != RS_RET_OK) { + curl_slist_free_all(slist); + LogError(0, iRet, "omhttp: error allocating curl header slist, using previous one"); + } + RETiRet; +} + + + +static rsRetVal ATTR_NONNULL(1, 2) +curlPost(wrkrInstanceData_t *pWrkrData, uchar *message, int msglen, uchar **tpls, + const int nmsgs __attribute__((unused))) +{ + CURLcode curlCode; + CURL *const curl = pWrkrData->curlPostHandle; + char errbuf[CURL_ERROR_SIZE] = ""; + + char *postData; + int postLen; + sbool compressed; + DEFiRet; + + PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); + + if(pWrkrData->pData->numServers > 1) { + /* needs to be called to support ES HA feature */ + CHKiRet(checkConn(pWrkrData)); + } + CHKiRet(setPostURL(pWrkrData, tpls)); + + pWrkrData->reply = NULL; + pWrkrData->replyLen = 0; + pWrkrData->httpStatusCode = 0; + + postData = (char *)message; + postLen = msglen; + compressed = 0; + + if (pWrkrData->pData->compress) { + iRet = compressHttpPayload(pWrkrData, message, msglen); + if (iRet != RS_RET_OK) { + LogError(0, iRet, "omhttp: curlPost error while compressing, will default to uncompressed"); + } else { + postData = (char *)pWrkrData->compressCtx.buf; + postLen = pWrkrData->compressCtx.curLen; + compressed = 1; + DBGPRINTF("omhttp: curlPost compressed %d to %d bytes\n", msglen, postLen); + } + } + + buildCurlHeaders(pWrkrData, compressed); + + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postLen); + curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_HTTPHEADER, pWrkrData->curlHeader); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); + + curlCode = curl_easy_perform(curl); + DBGPRINTF("omhttp: curlPost curl returned %lld\n", (long long) curlCode); + STATSCOUNTER_INC(ctrHttpRequestCount, mutCtrHttpRequestCount); + + if (curlCode != CURLE_OK) { + STATSCOUNTER_INC(ctrHttpRequestFail, mutCtrHttpRequestFail); + LogError(0, RS_RET_SUSPENDED, + "omhttp: suspending ourselves due to server failure %lld: %s", + (long long) curlCode, errbuf); + // Check the result here too and retry if needed, then we should suspend + // Usually in batch mode we clobber any iRet values, but probably not a great + // idea to keep hitting a dead server. The http status code will be 0 at this point. + checkResult(pWrkrData, message); + ABORT_FINALIZE(RS_RET_SUSPENDED); + } else { + STATSCOUNTER_INC(ctrHttpRequestSuccess, mutCtrHttpRequestSuccess); + } + + // Grab the HTTP Response code + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &pWrkrData->httpStatusCode); + if(pWrkrData->reply == NULL) { + DBGPRINTF("omhttp: curlPost pWrkrData reply==NULL, replyLen = '%d'\n", + pWrkrData->replyLen); + } else { + DBGPRINTF("omhttp: curlPost pWrkrData replyLen = '%d'\n", pWrkrData->replyLen); + if(pWrkrData->replyLen > 0) { + pWrkrData->reply[pWrkrData->replyLen] = '\0'; + /* Append 0 Byte if replyLen is above 0 - byte has been reserved in malloc */ + } + //TODO: replyLen++? because 0 Byte is appended + DBGPRINTF("omhttp: curlPost pWrkrData reply: '%s'\n", pWrkrData->reply); + } + CHKiRet(checkResult(pWrkrData, message)); + +finalize_it: + incrementServerIndex(pWrkrData); + if (pWrkrData->reply != NULL) { + free(pWrkrData->reply); + pWrkrData->reply = NULL; /* don't leave dangling pointer */ + } + RETiRet; +} + +/* Build a JSON batch that conforms to the Kafka Rest Proxy format. + * See https://docs.confluent.io/current/kafka-rest/docs/quickstart.html for more info. + * Want {"records": [{"value": "message1"}, {"value": "message2"}]} + */ +static rsRetVal +serializeBatchKafkaRest(wrkrInstanceData_t *pWrkrData, char **batchBuf) +{ + fjson_object *batchArray = NULL; + fjson_object *recordObj = NULL; + fjson_object *valueObj = NULL; + fjson_object *msgObj = NULL; + + size_t numMessages = pWrkrData->batch.nmemb; + size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages + 1; // messages + brackets + commas + DBGPRINTF("omhttp: serializeBatchKafkaRest numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); + + DEFiRet; + + batchArray = fjson_object_new_array(); + if (batchArray == NULL) { + LogError(0, RS_RET_ERR, "omhttp: serializeBatchKafkaRest failed to create array"); + ABORT_FINALIZE(RS_RET_ERR); + } + + for (size_t i = 0; i < numMessages; i++) { + valueObj = fjson_object_new_object(); + if (valueObj == NULL) { + fjson_object_put(batchArray); // cleanup + LogError(0, RS_RET_ERR, "omhttp: serializeBatchKafkaRest failed to create value object"); + ABORT_FINALIZE(RS_RET_ERR); + } + + msgObj = fjson_tokener_parse((char *) pWrkrData->batch.data[i]); + if (msgObj == NULL) { + LogError(0, NO_ERRCODE, + "omhttp: serializeBatchKafkaRest failed to parse %s as json ignoring it", + pWrkrData->batch.data[i]); + continue; + } + fjson_object_object_add(valueObj, "value", msgObj); + fjson_object_array_add(batchArray, valueObj); + } + + recordObj = fjson_object_new_object(); + if (recordObj == NULL) { + fjson_object_put(batchArray); // cleanup + LogError(0, RS_RET_ERR, "omhttp: serializeBatchKafkaRest failed to create record object"); + ABORT_FINALIZE(RS_RET_ERR); + } + + fjson_object_object_add(recordObj, "records", batchArray); + + const char *batchString = fjson_object_to_json_string_ext(recordObj, FJSON_TO_STRING_PLAIN); + *batchBuf = strndup(batchString, strlen(batchString)); + +finalize_it: + if (recordObj != NULL) { + fjson_object_put(recordObj); + recordObj = NULL; + } + + RETiRet; +} + +static rsRetVal +serializeBatchLokiRest(wrkrInstanceData_t *pWrkrData, char **batchBuf) +{ + fjson_object *batchArray = NULL; + fjson_object *recordObj = NULL; + fjson_object *msgObj = NULL; + + size_t numMessages = pWrkrData->batch.nmemb; + size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages + 1; // messages + brackets + commas + DBGPRINTF("omhttp: serializeBatchLokiRest numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); + + DEFiRet; + + batchArray = fjson_object_new_array(); + if (batchArray == NULL) { + LogError(0, RS_RET_ERR, "omhttp: serializeBatchLokiRest failed to create array"); + ABORT_FINALIZE(RS_RET_ERR); + } + + for (size_t i = 0; i < numMessages; i++) { + DBGPRINTF("omhttp: serializeBatchLokiRest parsing message [%s]\n",(char *) pWrkrData->batch.data[i]); + msgObj = fjson_tokener_parse((char *) pWrkrData->batch.data[i]); + if (msgObj == NULL) { + LogError(0, NO_ERRCODE, + "omhttp: serializeBatchLokiRest failed to parse %s as json ignoring it", + pWrkrData->batch.data[i]); + continue; + } + fjson_object_array_add(batchArray, msgObj); + } + + recordObj = fjson_object_new_object(); + if (recordObj == NULL) { + fjson_object_put(batchArray); // cleanup + LogError(0, RS_RET_ERR, "omhttp: serializeBatchLokiRest failed to create record object"); + ABORT_FINALIZE(RS_RET_ERR); + } + + fjson_object_object_add(recordObj, "streams", batchArray); + + const char *batchString = fjson_object_to_json_string_ext(recordObj, FJSON_TO_STRING_PLAIN); + *batchBuf = strndup(batchString, strlen(batchString)); + +finalize_it: + if (recordObj != NULL) { + fjson_object_put(recordObj); + recordObj = NULL; + } + + RETiRet; +} +/* Build a JSON batch by placing each element in an array. + */ +static rsRetVal +serializeBatchJsonArray(wrkrInstanceData_t *pWrkrData, char **batchBuf) +{ + fjson_object *batchArray = NULL; + fjson_object *msgObj = NULL; + size_t numMessages = pWrkrData->batch.nmemb; + size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages + 1; // messages + brackets + commas + DBGPRINTF("omhttp: serializeBatchJsonArray numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); + + DEFiRet; + + batchArray = fjson_object_new_array(); + if (batchArray == NULL) { + LogError(0, RS_RET_ERR, "omhttp: serializeBatchJsonArray failed to create array"); + ABORT_FINALIZE(RS_RET_ERR); + } + + for (size_t i = 0; i < numMessages; i++) { + msgObj = fjson_tokener_parse((char *) pWrkrData->batch.data[i]); + if (msgObj == NULL) { + LogError(0, NO_ERRCODE, + "omhttp: serializeBatchJsonArray failed to parse %s as json, ignoring it", + pWrkrData->batch.data[i]); + continue; + } + fjson_object_array_add(batchArray, msgObj); + } + + const char *batchString = fjson_object_to_json_string_ext(batchArray, FJSON_TO_STRING_PLAIN); + *batchBuf = strndup(batchString, strlen(batchString)); + +finalize_it: + if (batchArray != NULL) { + fjson_object_put(batchArray); + batchArray = NULL; + } + RETiRet; +} + +/* Build a batch by joining each element with a newline character. + */ +static rsRetVal +serializeBatchNewline(wrkrInstanceData_t *pWrkrData, char **batchBuf) +{ + DEFiRet; + size_t numMessages = pWrkrData->batch.nmemb; + size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages; // message + newline + null term + int r = 0; + + DBGPRINTF("omhttp: serializeBatchNewline numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); + + es_str_t *batchString = es_newStr(1024); + + if (batchString == NULL) + ABORT_FINALIZE(RS_RET_ERR); + + for (size_t i = 0; i < numMessages; i++) { + size_t nToCopy = ustrlen(pWrkrData->batch.data[i]); + if (r == 0) r = es_addBuf(&batchString, (char *)pWrkrData->batch.data[i], nToCopy); + if (i == numMessages - 1) break; + if (r == 0) r = es_addChar(&batchString, '\n'); + } + + if (r == 0) *batchBuf = (char *) es_str2cstr(batchString, NULL); + + if (r != 0 || *batchBuf== NULL) { + LogError(0, RS_RET_ERR, "omhttp: serializeBatchNewline failed to build batch string"); + ABORT_FINALIZE(RS_RET_ERR); + } + +finalize_it: + if (batchString != NULL) + es_deleteStr(batchString); + + RETiRet; +} + +/* Return the final batch size in bytes for each serialization method. + * Used to decide if a batch should be flushed early. + */ +static size_t +computeBatchSize(wrkrInstanceData_t *pWrkrData) +{ + size_t extraBytes = 0; + size_t sizeBytes = pWrkrData->batch.sizeBytes; + size_t numMessages = pWrkrData->batch.nmemb; + + switch (pWrkrData->pData->batchFormat) { + case FMT_JSONARRAY: + // square brackets, commas between each message + // 2 + numMessages - 1 = numMessages + 1 + extraBytes = numMessages > 0 ? numMessages + 1 : 2; + break; + case FMT_KAFKAREST: + // '{}', '[]', '"records":'= 2 + 2 + 10 = 14 + // '{"value":}' for each message = n * 10 + // numMessages == 0 handled implicitly in multiplication + extraBytes = (numMessages * 10) + 14; + break; + case FMT_NEWLINE: + // newlines between each message + extraBytes = numMessages > 0 ? numMessages - 1 : 0; + break; + case FMT_LOKIREST: + // {"streams":[ '{}', '[]', '"streams":' = 14 + // {"stream": {key:value}..., "values":[[timestamp: msg1]]}, + // {"stream": {key:value}..., "values":[[timestamp: msg2]]} + // ]} + // message (11) * numMessages + header ( 16 ) + extraBytes = (numMessages * 2) + 14; + break; + default: + // newlines between each message + extraBytes = numMessages > 0 ? numMessages - 1 : 0; + } + + return sizeBytes + extraBytes + 1; // plus a null +} + +static void ATTR_NONNULL() +initializeBatch(wrkrInstanceData_t *pWrkrData) +{ + pWrkrData->batch.sizeBytes = 0; + pWrkrData->batch.nmemb = 0; + if (pWrkrData->batch.restPath != NULL) { + free(pWrkrData->batch.restPath); + pWrkrData->batch.restPath = NULL; + } +} + +/* Adds a message to this worker's batch + */ +static rsRetVal +buildBatch(wrkrInstanceData_t *pWrkrData, uchar *message) +{ + DEFiRet; + + if (pWrkrData->batch.nmemb >= pWrkrData->pData->maxBatchSize) { + LogError(0, RS_RET_ERR, "omhttp: buildBatch something has gone wrong," + "number of messages in batch is bigger than the max batch size, bailing"); + ABORT_FINALIZE(RS_RET_ERR); + } + pWrkrData->batch.data[pWrkrData->batch.nmemb] = message; + pWrkrData->batch.sizeBytes += strlen((char *)message); + pWrkrData->batch.nmemb++; + +finalize_it: + RETiRet; +} + +static rsRetVal +submitBatch(wrkrInstanceData_t *pWrkrData, uchar **tpls) +{ + DEFiRet; + char *batchBuf = NULL; + + switch (pWrkrData->pData->batchFormat) { + case FMT_JSONARRAY: + iRet = serializeBatchJsonArray(pWrkrData, &batchBuf); + break; + case FMT_KAFKAREST: + iRet = serializeBatchKafkaRest(pWrkrData, &batchBuf); + break; + case FMT_LOKIREST: + iRet = serializeBatchLokiRest(pWrkrData, &batchBuf); + break; + case FMT_NEWLINE: + iRet = serializeBatchNewline(pWrkrData, &batchBuf); + break; + default: + iRet = serializeBatchNewline(pWrkrData, &batchBuf); + } + + if (iRet != RS_RET_OK || batchBuf == NULL) + ABORT_FINALIZE(iRet); + + DBGPRINTF("omhttp: submitBatch, batch: '%s' tpls: '%p'\n", batchBuf, tpls); + + CHKiRet(curlPost(pWrkrData, (uchar*) batchBuf, strlen(batchBuf), + tpls, pWrkrData->batch.nmemb)); + +finalize_it: + if (batchBuf != NULL) + free(batchBuf); + RETiRet; +} + +BEGINbeginTransaction +CODESTARTbeginTransaction + if(!pWrkrData->pData->batchMode) { + FINALIZE; + } + + initializeBatch(pWrkrData); +finalize_it: +ENDbeginTransaction + +BEGINdoAction +size_t nBytes; +sbool submit; +CODESTARTdoAction + instanceData *const pData = pWrkrData->pData; + uchar *restPath = NULL; + STATSCOUNTER_INC(ctrMessagesSubmitted, mutCtrMessagesSubmitted); + + if (pWrkrData->pData->batchMode) { + if(pData->dynRestPath) { + /* Get copy of restpath in batch mode if dynRestPath enabled */ + getRestPath(pData, ppString, &restPath); + if (pWrkrData->batch.restPath == NULL) { + pWrkrData->batch.restPath = (uchar*)strdup((char*)restPath); + } else if (strcmp((char*)pWrkrData->batch.restPath, (char*)restPath) != 0) { + /* Check if the restPath changed - if yes submit the current batch first*/ + CHKiRet(submitBatch(pWrkrData, NULL)); + initializeBatch(pWrkrData); + } + } + + /* If the maxbatchsize is 1, then build and immediately post a batch with 1 element. + * This mode will play nicely with rsyslog's action.resumeRetryCount logic. + */ + if (pWrkrData->pData->maxBatchSize == 1) { + initializeBatch(pWrkrData); + CHKiRet(buildBatch(pWrkrData, ppString[0])); + CHKiRet(submitBatch(pWrkrData, ppString)); + FINALIZE; + } + + /* We should submit if any of these conditions are true + * 1. Total batch size > pWrkrData->pData->maxBatchSize + * 2. Total bytes > pWrkrData->pData->maxBatchBytes + */ + nBytes = ustrlen((char *)ppString[0]) - 1 ; + submit = 0; + + if (pWrkrData->batch.nmemb >= pWrkrData->pData->maxBatchSize) { + submit = 1; + DBGPRINTF("omhttp: maxbatchsize limit reached submitting batch of %zd elements.\n", + pWrkrData->batch.nmemb); + } else if (computeBatchSize(pWrkrData) + nBytes > pWrkrData->pData->maxBatchBytes) { + submit = 1; + DBGPRINTF("omhttp: maxbytes limit reached submitting partial batch of %zd elements.\n", + pWrkrData->batch.nmemb); + } + + if (submit) { + CHKiRet(submitBatch(pWrkrData, ppString)); + initializeBatch(pWrkrData); + } + + CHKiRet(buildBatch(pWrkrData, ppString[0])); + + /* If there is only one item in the batch, all previous items have been + * submitted or this is the first item for this transaction. Return previous + * committed so that all items leading up to the current (exclusive) + * are not replayed should a failure occur anywhere else in the transaction. */ + iRet = pWrkrData->batch.nmemb == 1 ? RS_RET_PREVIOUS_COMMITTED : RS_RET_DEFER_COMMIT; + } else { + CHKiRet(curlPost(pWrkrData, ppString[0], strlen((char*)ppString[0]), ppString, 1)); + } +finalize_it: +ENDdoAction + + +BEGINendTransaction +CODESTARTendTransaction + /* End Transaction only if batch data is not empty */ + if (pWrkrData->batch.nmemb > 0) { + CHKiRet(submitBatch(pWrkrData, NULL)); + } else { + dbgprintf("omhttp: endTransaction, pWrkrData->batch.nmemb = 0, " + "nothing to send. \n"); + } +finalize_it: +ENDendTransaction + +/* Creates authentication header uid:pwd + */ +static rsRetVal +computeAuthHeader(char* uid, char* pwd, uchar** authBuf) +{ + int r; + DEFiRet; + + es_str_t* auth = es_newStr(1024); + if (auth == NULL) { + LogError(0, RS_RET_OUT_OF_MEMORY, + "omhttp: failed to allocate es_str auth for auth header construction"); + ABORT_FINALIZE(RS_RET_ERR); + } + + r = es_addBuf(&auth, uid, strlen(uid)); + if(r == 0) r = es_addChar(&auth, ':'); + if(r == 0 && pwd != NULL) r = es_addBuf(&auth, pwd, strlen(pwd)); + if(r == 0) *authBuf = (uchar*) es_str2cstr(auth, NULL); + + if (r != 0 || *authBuf == NULL) { + LogError(0, RS_RET_ERR, "omhttp: failed to build auth header\n"); + ABORT_FINALIZE(RS_RET_ERR); + } + +finalize_it: + if (auth != NULL) + es_deleteStr(auth); + RETiRet; +} + +static rsRetVal +computeApiHeader(char* key, char* value, uchar** headerBuf) +{ + int r; + DEFiRet; + + es_str_t* header = es_newStr(10240); + if (header == NULL) { + LogError(0, RS_RET_OUT_OF_MEMORY, + "omhttp: failed to allocate es_str auth for api header construction"); + ABORT_FINALIZE(RS_RET_ERR); + } + + r = es_addBuf(&header, key, strlen(key)); + if(r == 0) r = es_addChar(&header, ':'); + if(r == 0) r = es_addChar(&header, ' '); + if(r == 0 && value != NULL) r = es_addBuf(&header, value, strlen(value)); + if(r == 0) *headerBuf = (uchar*) es_str2cstr(header, NULL); + + if (r != 0 || *headerBuf == NULL) { + LogError(0, RS_RET_ERR, "omhttp: failed to build http header\n"); + ABORT_FINALIZE(RS_RET_ERR); + } + +finalize_it: + if (header != NULL) + es_deleteStr(header); + RETiRet; +} + +static void ATTR_NONNULL() +curlSetupCommon(wrkrInstanceData_t *const pWrkrData, CURL *const handle) +{ + PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, pWrkrData->curlHeader); + curl_easy_setopt(handle, CURLOPT_NOSIGNAL, TRUE); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curlResult); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, pWrkrData); + if(pWrkrData->pData->allowUnsignedCerts) + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, FALSE); + if(pWrkrData->pData->skipVerifyHost) + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, FALSE); + if(pWrkrData->pData->authBuf != NULL) { + curl_easy_setopt(handle, CURLOPT_USERPWD, pWrkrData->pData->authBuf); + curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY); + } + if(pWrkrData->pData->caCertFile) + curl_easy_setopt(handle, CURLOPT_CAINFO, pWrkrData->pData->caCertFile); + if(pWrkrData->pData->myCertFile) + curl_easy_setopt(handle, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile); + if(pWrkrData->pData->myPrivKeyFile) + curl_easy_setopt(handle, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile); + /* uncomment for in-dept debuggung: + curl_easy_setopt(handle, CURLOPT_VERBOSE, TRUE); */ +} + +static void ATTR_NONNULL() +curlCheckConnSetup(wrkrInstanceData_t *const pWrkrData) +{ + PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); + curlSetupCommon(pWrkrData, pWrkrData->curlCheckConnHandle); + curl_easy_setopt(pWrkrData->curlCheckConnHandle, + CURLOPT_TIMEOUT_MS, pWrkrData->pData->healthCheckTimeout); +} + +static void ATTR_NONNULL(1) +curlPostSetup(wrkrInstanceData_t *const pWrkrData) +{ + PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); + curlSetupCommon(pWrkrData, pWrkrData->curlPostHandle); + curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_POST, 1); + CURLcode cRet; + /* Enable TCP keep-alive for this transfer */ + cRet = curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_TCP_KEEPALIVE, 1L); + if (cRet != CURLE_OK) + DBGPRINTF("omhttp: curlPostSetup unknown option CURLOPT_TCP_KEEPALIVE\n"); + /* keep-alive idle time to 120 seconds */ + cRet = curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_TCP_KEEPIDLE, 120L); + if (cRet != CURLE_OK) + DBGPRINTF("omhttp: curlPostSetup unknown option CURLOPT_TCP_KEEPIDLE\n"); + /* interval time between keep-alive probes: 60 seconds */ + cRet = curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_TCP_KEEPINTVL, 60L); + if (cRet != CURLE_OK) + DBGPRINTF("omhttp: curlPostSetup unknown option CURLOPT_TCP_KEEPINTVL\n"); +} + +static rsRetVal ATTR_NONNULL() +curlSetup(wrkrInstanceData_t *const pWrkrData) +{ + struct curl_slist *slist = NULL; + + DEFiRet; + if (pWrkrData->pData->httpcontenttype != NULL) { + slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerContentTypeBuf); + } else { + slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); + } + + if (pWrkrData->pData->headerBuf != NULL) { + slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerBuf); + CHKmalloc(slist); + } + + for (int k = 0 ; k < pWrkrData->pData->nHttpHeaders; k++) { + slist = curl_slist_append(slist, (char *)pWrkrData->pData->httpHeaders[k]); + CHKmalloc(slist); + } + + // When sending more than 1Kb, libcurl automatically sends an Except: 100-Continue header + // and will wait 1s for a response, could make this configurable but for now disable + slist = curl_slist_append(slist, HTTP_HEADER_EXPECT_EMPTY); + pWrkrData->curlHeader = slist; + CHKmalloc(pWrkrData->curlPostHandle = curl_easy_init()); + curlPostSetup(pWrkrData); + + CHKmalloc(pWrkrData->curlCheckConnHandle = curl_easy_init()); + curlCheckConnSetup(pWrkrData); + +finalize_it: + if(iRet != RS_RET_OK && pWrkrData->curlPostHandle != NULL) { + curl_easy_cleanup(pWrkrData->curlPostHandle); + pWrkrData->curlPostHandle = NULL; + } + RETiRet; +} + +static void ATTR_NONNULL() +curlCleanup(wrkrInstanceData_t *const pWrkrData) +{ + if (pWrkrData->curlHeader != NULL) { + curl_slist_free_all(pWrkrData->curlHeader); + pWrkrData->curlHeader = NULL; + } + if (pWrkrData->curlCheckConnHandle != NULL) { + curl_easy_cleanup(pWrkrData->curlCheckConnHandle); + pWrkrData->curlCheckConnHandle = NULL; + } + if (pWrkrData->curlPostHandle != NULL) { + curl_easy_cleanup(pWrkrData->curlPostHandle); + pWrkrData->curlPostHandle = NULL; + } +} + +static void ATTR_NONNULL() +setInstParamDefaults(instanceData *const pData) +{ + pData->serverBaseUrls = NULL; + pData->defaultPort = 443; + pData->healthCheckTimeout = 3500; + pData->uid = NULL; + pData->httpcontenttype = NULL; + pData->headerContentTypeBuf = NULL; + pData->httpheaderkey = NULL; + pData->httpheadervalue = NULL; + pData->httpHeaders = NULL; + pData->nHttpHeaders = 0; + pData->pwd = NULL; + pData->authBuf = NULL; + pData->restPath = NULL; + pData->checkPath = NULL; + pData->dynRestPath = 0; + pData->batchMode = 0; + pData->batchFormatName = (uchar *)"newline"; + pData->batchFormat = FMT_NEWLINE; + pData->bFreeBatchFormatName = 0; + pData->useHttps = 1; + pData->maxBatchBytes = 10485760; //i.e. 10 MB Is the default max message size for AWS API Gateway + pData->maxBatchSize = 100; // 100 messages + pData->compress = 0; // off + pData->compressionLevel = -1; // default compression + pData->allowUnsignedCerts = 0; + pData->skipVerifyHost = 0; + pData->tplName = NULL; + pData->errorFile = NULL; + pData->caCertFile = NULL; + pData->myCertFile = NULL; + pData->myPrivKeyFile = NULL; + pData->reloadOnHup= 0; + pData->retryFailures = 0; + pData->ratelimitBurst = 20000; + pData->ratelimitInterval = 600; + pData->ratelimiter = NULL; + pData->retryRulesetName = NULL; + pData->retryRuleset = NULL; +} + +static rsRetVal +checkHeaderParam(char *const param) +{ + DEFiRet; + char *val = strstr(param, ":"); + if(val == NULL) { + LogError(0, RS_RET_PARAM_ERROR, "missing ':' delimiter in " + "parameter '%s'", param); + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } +finalize_it: + RETiRet; +} + +BEGINnewActInst + struct cnfparamvals *pvals; + char* serverParam = NULL; + struct cnfarray* servers = NULL; + int i; + int iNumTpls; + FILE *fp; + char errStr[1024]; + char *batchFormatName; + int compressionLevel = -1; +CODESTARTnewActInst + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(actpblk.descr[i].name, "server")) { + servers = pvals[i].val.d.ar; + } else if(!strcmp(actpblk.descr[i].name, "errorfile")) { + pData->errorFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "serverport")) { + pData->defaultPort = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "healthchecktimeout")) { + pData->healthCheckTimeout = (long) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "uid")) { + pData->uid = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "httpcontenttype")) { + pData->httpcontenttype = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "httpheaderkey")) { + pData->httpheaderkey = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "httpheadervalue")) { + pData->httpheadervalue = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "httpheaders")) { + pData->nHttpHeaders = pvals[i].val.d.ar->nmemb; + CHKmalloc(pData->httpHeaders = malloc(sizeof(uchar *) * pvals[i].val.d.ar->nmemb )); + for(int j = 0 ; j < pvals[i].val.d.ar->nmemb ; ++j) { + char *cstr = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); + CHKiRet(checkHeaderParam(cstr)); + pData->httpHeaders[j] = (uchar *)cstr; + } + } else if(!strcmp(actpblk.descr[i].name, "pwd")) { + pData->pwd = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "restpath")) { + pData->restPath = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "checkpath")) { + pData->checkPath = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "dynrestpath")) { + pData->dynRestPath = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "batch")) { + pData->batchMode = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "batch.format")) { + batchFormatName = es_str2cstr(pvals[i].val.d.estr, NULL); + if (strstr(VALID_BATCH_FORMATS, batchFormatName) != NULL) { + pData->batchFormatName = (uchar *)batchFormatName; + pData->bFreeBatchFormatName = 1; + if (!strcmp(batchFormatName, "newline")) { + pData->batchFormat = FMT_NEWLINE; + } else if (!strcmp(batchFormatName, "jsonarray")) { + pData->batchFormat = FMT_JSONARRAY; + } else if (!strcmp(batchFormatName, "kafkarest")) { + pData->batchFormat = FMT_KAFKAREST; + } else if (!strcmp(batchFormatName, "lokirest")) { + pData->batchFormat = FMT_LOKIREST; + } + } else { + LogError(0, NO_ERRCODE, "error: 'batch.format' %s unknown defaulting to 'newline'", + batchFormatName); + } + } else if(!strcmp(actpblk.descr[i].name, "batch.maxbytes")) { + pData->maxBatchBytes = (size_t) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "batch.maxsize")) { + pData->maxBatchSize = (size_t) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "compress")) { + pData->compress = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "compress.level")) { + compressionLevel = pvals[i].val.d.n; + if (compressionLevel == -1 || (compressionLevel >= 0 && compressionLevel < 10)) { + pData->compressionLevel = compressionLevel; + } else { + LogError(0, NO_ERRCODE, "omhttp: invalid compress.level %d using default instead," + "valid levels are -1 and 0-9", + compressionLevel); + } + } else if(!strcmp(actpblk.descr[i].name, "allowunsignedcerts")) { + pData->allowUnsignedCerts = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "skipverifyhost")) { + pData->skipVerifyHost = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "usehttps")) { + pData->useHttps = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "template")) { + pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "tls.cacert")) { + pData->caCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->caCertFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + LogError(0, RS_RET_NO_FILE_ACCESS, + "error: 'tls.cacert' file %s couldn't be accessed: %s\n", + pData->caCertFile, errStr); + } else { + fclose(fp); + } + } else if(!strcmp(actpblk.descr[i].name, "tls.mycert")) { + pData->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->myCertFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + LogError(0, RS_RET_NO_FILE_ACCESS, + "error: 'tls.mycert' file %s couldn't be accessed: %s\n", + pData->myCertFile, errStr); + } else { + fclose(fp); + } + } else if(!strcmp(actpblk.descr[i].name, "tls.myprivkey")) { + pData->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + fp = fopen((const char*)pData->myPrivKeyFile, "r"); + if(fp == NULL) { + rs_strerror_r(errno, errStr, sizeof(errStr)); + LogError(0, RS_RET_NO_FILE_ACCESS, + "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n", + pData->myPrivKeyFile, errStr); + } else { + fclose(fp); + } + } else if(!strcmp(actpblk.descr[i].name, "reloadonhup")) { + pData->reloadOnHup= pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "retry")) { + pData->retryFailures = pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "retry.ruleset")) { + pData->retryRulesetName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "ratelimit.burst")) { + pData->ratelimitBurst = (unsigned int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "ratelimit.interval")) { + pData->ratelimitInterval = (unsigned int) pvals[i].val.d.n; + } else { + LogError(0, RS_RET_INTERNAL_ERROR, "omhttp: program error, " + "non-handled param '%s'", actpblk.descr[i].name); + } + } + + if(pData->pwd != NULL && pData->uid == NULL) { + LogError(0, RS_RET_UID_MISSING, + "omhttp: password is provided, but no uid " + "- action definition invalid"); + ABORT_FINALIZE(RS_RET_UID_MISSING); + } + if(pData->httpheaderkey != NULL && pData->httpheadervalue == NULL) { + LogError(0, RS_RET_UID_MISSING, + "omhttp: http header key is provided, but no http header value " + "- action definition invalid"); + ABORT_FINALIZE(RS_RET_UID_MISSING); + } + if(pData->dynRestPath && pData->restPath == NULL) { + LogError(0, RS_RET_CONFIG_ERROR, + "omhttp: requested dynamic rest path, but no name for rest " + "path template given - action definition invalid"); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + if (pData->uid != NULL) + CHKiRet(computeAuthHeader((char*) pData->uid, (char*) pData->pwd, &pData->authBuf)); + if (pData->httpcontenttype != NULL) + CHKiRet(computeApiHeader((char*) "Content-Type", + (char*) pData->httpcontenttype, &pData->headerContentTypeBuf)); + + if (pData->httpheaderkey != NULL) + CHKiRet(computeApiHeader((char*) pData->httpheaderkey, + (char*) pData->httpheadervalue, &pData->headerBuf)); + + iNumTpls = 1; + if(pData->dynRestPath) ++iNumTpls; + DBGPRINTF("omhttp: requesting %d templates\n", iNumTpls); + CODE_STD_STRING_REQUESTnewActInst(iNumTpls) + + CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar*)strdup((pData->tplName == NULL) ? + " StdJSONFmt" : (char*)pData->tplName), + OMSR_NO_RQD_TPL_OPTS)); + + + /* we need to request additional templates. If we have a dynamic search index, + * it will always be string 1. Type may be 1 or 2, depending on whether search + * index is dynamic as well. Rule needs to be followed throughout the module. + */ + iNumTpls = 1; + if(pData->dynRestPath) { + CHKiRet(OMSRsetEntry(*ppOMSR, iNumTpls, ustrdup(pData->restPath), + OMSR_NO_RQD_TPL_OPTS)); + ++iNumTpls; + } + + if (servers != NULL) { + pData->numServers = servers->nmemb; + pData->serverBaseUrls = malloc(servers->nmemb * sizeof(uchar*)); + if (pData->serverBaseUrls == NULL) { + LogError(0, RS_RET_ERR, "omhttp: unable to allocate buffer " + "for http server configuration."); + ABORT_FINALIZE(RS_RET_ERR); + } + + for(i = 0 ; i < servers->nmemb ; ++i) { + serverParam = es_str2cstr(servers->arr[i], NULL); + if (serverParam == NULL) { + LogError(0, RS_RET_ERR, "omhttp: unable to allocate buffer " + "for http server configuration."); + ABORT_FINALIZE(RS_RET_ERR); + } + /* Remove a trailing slash if it exists */ + const size_t serverParamLastChar = strlen(serverParam)-1; + if (serverParam[serverParamLastChar] == '/') { + serverParam[serverParamLastChar] = '\0'; + } + CHKiRet(computeBaseUrl(serverParam, pData->defaultPort, pData->useHttps, + pData->serverBaseUrls + i)); + free(serverParam); + serverParam = NULL; + } + } else { + LogMsg(0, RS_RET_OK, LOG_WARNING, + "omhttp: No servers specified, using localhost"); + pData->numServers = 1; + pData->serverBaseUrls = malloc(sizeof(uchar*)); + if (pData->serverBaseUrls == NULL) { + LogError(0, RS_RET_ERR, "omhttp: unable to allocate buffer " + "for http server configuration."); + ABORT_FINALIZE(RS_RET_ERR); + } + CHKiRet(computeBaseUrl("localhost", pData->defaultPort, pData->useHttps, pData->serverBaseUrls)); + } + + if (pData->retryFailures) { + CHKiRet(ratelimitNew(&pData->ratelimiter, "omhttp", NULL)); + ratelimitSetLinuxLike(pData->ratelimiter, pData->ratelimitInterval, pData->ratelimitBurst); + ratelimitSetNoTimeCache(pData->ratelimiter); + } + + /* node created, let's add to list of instance configs for the module */ + if(loadModConf->tail == NULL) { + loadModConf->tail = loadModConf->root = pData; + } else { + loadModConf->tail->next = pData; + loadModConf->tail = pData; + } + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); + if (serverParam) + free(serverParam); +ENDnewActInst + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + loadModConf = pModConf; + pModConf->pConf = pConf; + pModConf->root = pModConf->tail = NULL; +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad + loadModConf = NULL; /* done loading */ +ENDendCnfLoad + + +BEGINcheckCnf + instanceConf_t *inst; +CODESTARTcheckCnf + for(inst = pModConf->root ; inst != NULL ; inst = inst->next) { + ruleset_t *pRuleset; + rsRetVal localRet; + + if (inst->retryRulesetName) { + localRet = ruleset.GetRuleset(pModConf->pConf, &pRuleset, inst->retryRulesetName); + if(localRet == RS_RET_NOT_FOUND) { + LogError(0, localRet, "omhttp: retry.ruleset '%s' not found - " + "no retry ruleset will be used", inst->retryRulesetName); + } else { + inst->retryRuleset = pRuleset; + } + } + } +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + +// HUP handling for the instance... +BEGINdoHUP +CODESTARTdoHUP + pthread_mutex_lock(&pData->mutErrFile); + if (pData->fdErrFile != -1) { + close(pData->fdErrFile); + pData->fdErrFile = -1; + } + pthread_mutex_unlock(&pData->mutErrFile); +ENDdoHUP + + +// HUP handling for the worker... +BEGINdoHUPWrkr +CODESTARTdoHUPWrkr + if (pWrkrData->pData->reloadOnHup) { + LogMsg(0, NO_ERRCODE, LOG_INFO, "omhttp: received HUP reloading curl handles"); + curlCleanup(pWrkrData); + CHKiRet(curlSetup(pWrkrData)); + } +finalize_it: +ENDdoHUPWrkr + + +BEGINmodExit +CODESTARTmodExit + if(pInputName != NULL) + prop.Destruct(&pInputName); + curl_global_cleanup(); + objRelease(prop, CORE_COMPONENT); + objRelease(ruleset, CORE_COMPONENT); + objRelease(statsobj, CORE_COMPONENT); + statsobj.Destruct(&httpStats); +ENDmodExit + +NO_LEGACY_CONF_parseSelectorAct + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +CODEqueryEtryPt_doHUP +CODEqueryEtryPt_doHUPWrkr /* Load the worker HUP handling code */ +CODEqueryEtryPt_TXIF_OMOD_QUERIES /* we support the transactional interface! */ +CODEqueryEtryPt_STD_CONF2_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(prop, CORE_COMPONENT)); + CHKiRet(objUse(ruleset, CORE_COMPONENT)); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); + + CHKiRet(statsobj.Construct(&httpStats)); + CHKiRet(statsobj.SetName(httpStats, (uchar *)"omhttp")); + CHKiRet(statsobj.SetOrigin(httpStats, (uchar*)"omhttp")); + + STATSCOUNTER_INIT(ctrMessagesSubmitted, mutCtrMessagesSubmitted); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"messages.submitted", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrMessagesSubmitted)); + + STATSCOUNTER_INIT(ctrMessagesSuccess, mutCtrMessagesSuccess); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"messages.success", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrMessagesSuccess)); + + STATSCOUNTER_INIT(ctrMessagesFail, mutCtrMessagesFail); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"messages.fail", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrMessagesFail)); + + STATSCOUNTER_INIT(ctrMessagesRetry, mutCtrMessagesRetry); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"messages.retry", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrMessagesRetry)); + + STATSCOUNTER_INIT(ctrHttpRequestCount, mutCtrHttpRequestCount); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"request.count", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrHttpRequestCount)); + + STATSCOUNTER_INIT(ctrHttpRequestSuccess, mutCtrHttpRequestSuccess); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"request.success", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrHttpRequestSuccess)); + + STATSCOUNTER_INIT(ctrHttpRequestFail, mutCtrHttpRequestFail); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"request.fail", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrHttpRequestFail)); + + STATSCOUNTER_INIT(ctrHttpStatusSuccess, mutCtrHttpStatusSuccess); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"request.status.success", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrHttpStatusSuccess)); + + STATSCOUNTER_INIT(ctrHttpStatusFail, mutCtrHttpStatusFail); + CHKiRet(statsobj.AddCounter(httpStats, (uchar *)"request.status.fail", + ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrHttpStatusFail)); + + CHKiRet(statsobj.ConstructFinalize(httpStats)); + + if (curl_global_init(CURL_GLOBAL_ALL) != 0) { + LogError(0, RS_RET_OBJ_CREATION_FAILED, "CURL fail. -http disabled"); + ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); + } + + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("omhttp"), sizeof("omhttp") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); +ENDmodInit + +/* vi:set ai: + */ diff --git a/contrib/omhttpfs/Makefile.am b/contrib/omhttpfs/Makefile.am new file mode 100644 index 0000000..d3af018 --- /dev/null +++ b/contrib/omhttpfs/Makefile.am @@ -0,0 +1,9 @@ +pkglib_LTLIBRARIES = omhttpfs.la + +omhttpfs_la_SOURCES = omhttpfs.c +omhttpfs_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBFASTJSON_CFLAGS) +omhttpfs_la_LDFLAGS = -module -avoid-version +omhttpfs_la_LIBADD = $(CURL_LIBS) $(LIBFASTJSON_LIBS) + + +EXTRA_DIST = diff --git a/contrib/omhttpfs/Makefile.in b/contrib/omhttpfs/Makefile.in new file mode 100644 index 0000000..a55d0bc --- /dev/null +++ b/contrib/omhttpfs/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omhttpfs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +omhttpfs_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_omhttpfs_la_OBJECTS = omhttpfs_la-omhttpfs.lo +omhttpfs_la_OBJECTS = $(am_omhttpfs_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omhttpfs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(omhttpfs_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omhttpfs_la_SOURCES) +DIST_SOURCES = $(omhttpfs_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omhttpfs.la +omhttpfs_la_SOURCES = omhttpfs.c +omhttpfs_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBFASTJSON_CFLAGS) +omhttpfs_la_LDFLAGS = -module -avoid-version +omhttpfs_la_LIBADD = $(CURL_LIBS) $(LIBFASTJSON_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omhttpfs/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omhttpfs/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omhttpfs.la: $(omhttpfs_la_OBJECTS) $(omhttpfs_la_DEPENDENCIES) $(EXTRA_omhttpfs_la_DEPENDENCIES) + $(AM_V_CCLD)$(omhttpfs_la_LINK) -rpath $(pkglibdir) $(omhttpfs_la_OBJECTS) $(omhttpfs_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omhttpfs_la-omhttpfs.lo: omhttpfs.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttpfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omhttpfs_la-omhttpfs.lo -MD -MP -MF $(DEPDIR)/omhttpfs_la-omhttpfs.Tpo -c -o omhttpfs_la-omhttpfs.lo `test -f 'omhttpfs.c' || echo '$(srcdir)/'`omhttpfs.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omhttpfs_la-omhttpfs.Tpo $(DEPDIR)/omhttpfs_la-omhttpfs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omhttpfs.c' object='omhttpfs_la-omhttpfs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttpfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omhttpfs_la-omhttpfs.lo `test -f 'omhttpfs.c' || echo '$(srcdir)/'`omhttpfs.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omhttpfs/omhttpfs.c b/contrib/omhttpfs/omhttpfs.c new file mode 100644 index 0000000..1bdacf6 --- /dev/null +++ b/contrib/omhttpfs/omhttpfs.c @@ -0,0 +1,855 @@ +/* omhttpfs.c + * Send all output to HDFS via httpfs + * + * Author: sskaje (sskaje@gmail.com, http://sskaje.me/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <curl/curl.h> +#include <json.h> +#include <json_object.h> + + +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "datetime.h" +#include "statsobj.h" +#include "unicode-helper.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omhttpfs") + +/* internal structures + */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(datetime) + +/* local definitions */ +#define OMHTTPFS_VERSION "1.0" +#define OMHTTPFS_DEFAULT_PORT 14000 +#define OMHTTPFS_DEFAULT_USER "hdfs" +#define OMHTTPFS_DEFAULT_HOST "127.0.0.1" + +#define HTTPFS_URL_PREFIX_V1 "/webhdfs/v1" +#define HTTPFS_URL_PREFIX_V1_SSL "/swebhdfs/v1" +#define HTTPFS_CONTENT_TYPE "Content-Type: application/octet-stream" +#define HTTPFS_USER_AGENT "omhttpfs by sskaje/" OMHTTPFS_VERSION + +#define HTTPFS_CONTENT_TYPE_JSON "application/json" +#define HTTPFS_JSON_BOOLEAN_TRUE "{\"boolean\":true}" + +#define HTTPFS_FILEALREADYEXISTSEXCEPTION "FileAlreadyExistsException" + +#define HTTPFS_URL_BUFFER_LENGTH 2048 + + +/* +Examples: + +module(load="omhttpfs") +template(name="hdfs_tmp_file" type="string" string="/tmp/%$YEAR%/test.log") +template(name="hdfs_tmp_filecontent" type="string" string="%$YEAR%-%$MONTH%-%$DAY% %MSG% ==\n") +local4.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on") +local5.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on" +template="hdfs_tmp_filecontent") + +*/ + +#define DPP(x) DBGPRINTF("OMHTTPFS: %s:%d %s(): %s\n", __FILE__, __LINE__, __FUNCTION__, x) + +/** + * Exception object + * + */ +typedef struct _HTTPFS_JSON_REMOTE_EXCEPTION { + char message[1024]; + char exception[256]; + char class[256]; +} httpfs_json_remote_exception; + + +typedef struct _instanceData { + sbool https; + uchar* host; + uchar* ip; + int port; + uchar* user; + + int timeout; + uchar* file; + sbool isDynFile; + + uchar* tplName; +} instanceData; + + +typedef struct wrkrInstanceData { + instanceData *pData; + + CURL* curl; + + uchar* file; + + int replyLen; + char* reply; +} wrkrInstanceData_t; + + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "host", eCmdHdlrGetWord, 0 }, + { "port", eCmdHdlrInt, 0 }, + { "user", eCmdHdlrGetWord, 0 }, + { "https", eCmdHdlrBinary, 0 }, + { "file", eCmdHdlrGetWord, CNFPARAM_REQUIRED }, + { "isdynfile", eCmdHdlrBinary, 0 }, + { "template", eCmdHdlrGetWord, 0 }, +}; +static struct cnfparamblk actpblk = { + CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr +}; + +/** + * curl init + * + * @param wrkrInstanceData_t *pWrkrData + * @param instanceData *pData + * @return rsRetVal + */ +static rsRetVal +httpfs_init_curl(wrkrInstanceData_t *pWrkrData, instanceData *pData) +{ + CURL *curl = NULL; + + curl = curl_easy_init(); + + if (curl) { + curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); + + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + + if (pData->https) { + DBGPRINTF("%s(): Enable HTTPS\n", __FUNCTION__); + /* for ssl */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + } + } else { + /* LOG */ + LogError(0, RS_RET_OBJ_CREATION_FAILED, "omhttpfs: failed to init cURL\n"); + + return RS_RET_OBJ_CREATION_FAILED; + } + + curl_easy_setopt(curl, CURLOPT_USERAGENT, HTTPFS_USER_AGENT); + + pWrkrData->curl = curl; + return RS_RET_OK; +} + +/** + * Build HTTPFS URL + * + * @param wrkrInstanceData_t *pWrkrData + * @param char* op + * @param es_str_t** url_buf + * @return rsRetVal + */ +static rsRetVal +httpfs_build_url(wrkrInstanceData_t *pWrkrData, const char* op, es_str_t** url_buf) +{ + *url_buf = es_newStr(HTTPFS_URL_BUFFER_LENGTH); + + if (pWrkrData->pData->https) { + es_addBuf(url_buf, "https://", sizeof("https://")-1); + } else { + es_addBuf(url_buf, "http://", sizeof("http://")-1); + } + + /* host */ + es_addBuf(url_buf, (char* )pWrkrData->pData->host, strlen((char*)pWrkrData->pData->host)); + + /* port */ + es_addChar(url_buf, ':'); + char portBuf[6]; + snprintf(portBuf, sizeof(portBuf), "%d", pWrkrData->pData->port); + es_addBuf(url_buf, portBuf, strlen(portBuf)); + + /* prefix */ + es_addBuf(url_buf, HTTPFS_URL_PREFIX_V1, sizeof(HTTPFS_URL_PREFIX_V1)-1); + + /* path */ + if (pWrkrData->file[0] != '/') { + es_addChar(url_buf, '/'); + } + es_addBuf(url_buf, (char* )pWrkrData->file, strlen((char* )pWrkrData->file)); + + /* queries */ + /* user */ + es_addBuf(url_buf, "?user.name=", sizeof("?user.name=")-1); + es_addBuf(url_buf, (char* )pWrkrData->pData->user, strlen((char* )pWrkrData->pData->user)); + + /* extra parameters */ + es_addBuf(url_buf, op, strlen(op)); + + return RS_RET_OK; +} + +/** + * curl set URL + * + * @param wrkrInstanceData_t *pWrkrData + * @param char* op + * @return void + */ +static void httpfs_set_url(wrkrInstanceData_t *pWrkrData, const char* op) +{ + es_str_t* url; + char* url_cstr; + httpfs_build_url(pWrkrData, op, &url); + url_cstr = es_str2cstr(url, NULL); + + curl_easy_setopt(pWrkrData->curl, CURLOPT_URL, url_cstr); + free(url_cstr); +} +/** + * Set http method to PUT + * + * @param CURL* curl + * @return void + */ +static void httpfs_curl_set_put(CURL* curl) +{ + curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L); + curl_easy_setopt(curl, CURLOPT_NOBODY, 0L); + curl_easy_setopt(curl, CURLOPT_POST, 0L); + curl_easy_setopt(curl, CURLOPT_PUT, 0L); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 0L); + + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); +} +/** + * Set http method to POST + * + * @param CURL* curl + * @return void + */ +static void httpfs_curl_set_post(CURL* curl) +{ + curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L); + curl_easy_setopt(curl, CURLOPT_NOBODY, 0L); + curl_easy_setopt(curl, CURLOPT_PUT, 0L); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 0L); + curl_easy_setopt(curl, CURLOPT_POST, 1L); + + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); +} + +/** + * Build curl slist + * + * @param struct curl_slist* headers + * @param int hdr_count + * @param ... + * @return struct curl_slist* + */ +static struct curl_slist* +httpfs_curl_add_header(struct curl_slist* headers, int hdr_count, ...) +{ + const char* hdr; + + va_list ar; + va_start(ar, hdr_count); + for (; hdr_count > 0; hdr_count--) { + hdr = va_arg(ar, const char*); + + if (hdr != NULL + && hdr[0] != 0) { + /* non-empty string */ + headers = curl_slist_append(headers, hdr); + } else { + break; + } + } + va_end(ar); + + headers = curl_slist_append(headers, "Expect:"); + headers = curl_slist_append(headers, "Transfer-Encoding:"); + + return headers; +} + +/** + * Callback function for CURLOPT_WRITEFUNCTION + * + * @param void* contents + * @param size_t size + * @param size_t nmemb + * @param void *userp + * @return size_t + */ +static size_t +httpfs_curl_result_callback(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + char *newreply = NULL; + wrkrInstanceData_t *mem = (wrkrInstanceData_t *)userp; + + newreply = realloc(mem->reply, mem->replyLen + realsize + 1); + if (newreply == NULL) { + /* out of memory! */ + dbgprintf("not enough memory (realloc returned NULL)\n"); + + if (mem->reply != NULL) + free(mem->reply); + + mem->reply = NULL; + mem->replyLen = 0; + + return 0; + } + + mem->reply = newreply; + memcpy(&(mem->reply[mem->replyLen]), contents, realsize); + mem->replyLen += realsize; + mem->reply[mem->replyLen] = 0; + + return realsize; +} + +/** + * Variables declaration + * used in httpfs related operation + */ +#define HTTPFS_CURL_VARS_INIT \ + struct curl_slist* headers = NULL; \ + long response_code; \ + CURLcode res; \ + char* content_type; + +/** + * Resource release + * used in httpfs related operation + */ +#define HTTPFS_CURL_VARS_RELEASE \ + curl_slist_free_all(headers); + +/** + * Curl execution + * used in httpfs related operation + */ +#define HTTPFS_CURL_EXEC \ + pWrkrData->reply = NULL; \ + pWrkrData->replyLen = 0; \ + curl_easy_setopt(pWrkrData->curl, CURLOPT_WRITEDATA, pWrkrData); \ + curl_easy_setopt(pWrkrData->curl, CURLOPT_WRITEFUNCTION, httpfs_curl_result_callback); \ + res = curl_easy_perform(pWrkrData->curl); \ + if (res == CURLE_OK) { \ + curl_easy_getinfo(pWrkrData->curl, CURLINFO_CONTENT_TYPE, &content_type); \ + if (strncmp(content_type, HTTPFS_CONTENT_TYPE_JSON, strlen(HTTPFS_CONTENT_TYPE_JSON))) { \ + } \ + curl_easy_getinfo(pWrkrData->curl, CURLINFO_RESPONSE_CODE, &response_code); \ + if (pWrkrData->reply != NULL) { \ + pWrkrData->reply[pWrkrData->replyLen] = '\0'; \ + } \ + } else { \ + LogError(0, RS_RET_ERR, "CURL request fail, code=%d, error string=%s\n", res, curl_easy_strerror(res)); \ + return -1; \ + } + +/** + * Parse remote exception json string + * + * @param char* buf + * @param int length + * @param httpfs_json_remote_exception* jre + * @return rsRetVal + */ +static rsRetVal +httpfs_parse_exception(char* buf, int length, httpfs_json_remote_exception* jre) +{ + DEFiRet; + + if (!length) { + return RS_RET_JSON_PARSE_ERR; + } + + struct json_tokener* jt = json_tokener_new(); + json_tokener_reset(jt); + + struct json_object *json; + json = json_tokener_parse_ex(jt, buf, length); + if (!json_object_is_type(json, json_type_object)) { + ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR); + } + + if (!json_object_object_get_ex(json, "RemoteException", &json)) { + ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR); + } + + struct json_object *jobj; + + memset(jre, 0, sizeof(*jre)); + + const char *str; + + json_object_object_get_ex(json, "javaClassName", &jobj); + str = json_object_get_string(jobj); + strncpy(jre->class, str, sizeof(jre->class)); + jre->class[sizeof(jre->class)-1] = '\0'; + + json_object_object_get_ex(json, "exception", &jobj); + str = json_object_get_string(jobj); + strncpy(jre->exception, str, sizeof(jre->exception)); + jre->exception[sizeof(jre->exception)-1] = '\0'; + + json_object_object_get_ex(json, "message", &jobj); + str = json_object_get_string(jobj); + strncpy(jre->message, str, sizeof(jre->message)); + jre->message[sizeof(jre->message)-1] = '\0'; + +finalize_it: + if(jt != NULL) + json_tokener_free(jt); + if(json != NULL) + json_object_put(json); + RETiRet; +} + + + +/** + * Create a file + * op=CREATE + * overwrite is turned off + * + * @param wrkrInstanceData_t *pWrkrData + * @param char* buf + * @return rsRetVal + */ +static rsRetVal +httpfs_create_file(wrkrInstanceData_t *pWrkrData, uchar* buf) +{ + /* httpfs.create automatically create folders, no mkdirs needed. */ + + /* + curl -b /tmp/c.tmp -c /tmp/c.tmp -d 'aaaaabbbbb' -i -H 'Content-Type: application/octet-stream' -X PUT \ + 'http://172.16.3.20:14000/webhdfs/v1/tmp/a/b?user.name=hdfs&op=create&data=true' + */ +HTTPFS_CURL_VARS_INIT + DBGPRINTF("%s(): file=%s\n", __FUNCTION__, pWrkrData->file); + httpfs_curl_set_put(pWrkrData->curl); + + /* +overwrite - if a file with this name already exists, then if true, the file will be overwritten, and if +false an error will be thrown. +bufferSize - the size of the buffer to be used. +replication - required block replication for the file. + */ + httpfs_set_url(pWrkrData, "&op=create&overwrite=false&data=true"); + + curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDS, (char*)buf); + curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDSIZE, strlen((char*) buf)); + + DBGPRINTF("%s(): msg=%s\n", __FUNCTION__, buf); + + headers = httpfs_curl_add_header(headers, 1, HTTPFS_CONTENT_TYPE); + curl_easy_setopt(pWrkrData->curl, CURLOPT_HTTPHEADER, headers); + +HTTPFS_CURL_EXEC + + int success = 0; + + if (response_code == 201) { + success = 1; + } + +HTTPFS_CURL_VARS_RELEASE + if (success) { + return RS_RET_OK; + } else { + return RS_RET_FALSE; + } +} + +/** + * Append to file + * op=APPEND + * + * @param wrkrInstanceData_t *pWrkrData + * @param char* buf + * @return rsRetVal + */ +static rsRetVal +httpfs_append_file(wrkrInstanceData_t *pWrkrData, uchar* buf) +{ + /* + curl -b /tmp/c.tmp -c /tmp/c.tmp -d 'aaaaabbbbb' -i -H 'Content-Type: application/octet-stream' \ + 'http://172.16.3.20:14000/webhdfs/v1/tmp/a/b?user.name=hdfs&op=append&data=true' + */ +HTTPFS_CURL_VARS_INIT + DBGPRINTF("%s(): file=%s\n", __FUNCTION__, pWrkrData->file); + httpfs_curl_set_post(pWrkrData->curl); + httpfs_set_url(pWrkrData, "&op=append&data=true"); + + curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDS, (char*)buf); + curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDSIZE, strlen((char*) buf)); + + headers = httpfs_curl_add_header(headers, 1, HTTPFS_CONTENT_TYPE); + curl_easy_setopt(pWrkrData->curl, CURLOPT_HTTPHEADER, headers); + DBGPRINTF("%s(): msg=%s\n", __FUNCTION__, buf); + +HTTPFS_CURL_EXEC + + int success = 0; + + if (response_code == 200) { + success = 1; + } else if (response_code == 404) { + /* TODO: 404 ? */ + + } +HTTPFS_CURL_VARS_RELEASE + if (success) { + return RS_RET_OK; + } else { + return RS_RET_FALSE; + } +} + + +/** + * httpfs log + * + * @param wrkrInstanceData_t *pWrkrData + * @param uchar* buf + * @return rsRetVal + */ +static rsRetVal +httpfs_log(wrkrInstanceData_t *pWrkrData, uchar* buf) +{ + /** + append ? 200/end : (404 || ?) + create & ~overwrite ? 201/200/end : + append ? 200/end : error ? + + + */ + DEFiRet; + + long response_code; + httpfs_json_remote_exception jre; + + iRet = httpfs_append_file(pWrkrData, buf); + if (iRet == RS_RET_OK) { + DBGPRINTF("omhttpfs: Append success: %s\n", pWrkrData->file); + return RS_RET_OK; + } + + curl_easy_getinfo(pWrkrData->curl, CURLINFO_RESPONSE_CODE, &response_code); + if (response_code != 404) { + /* TODO: log error */ + DBGPRINTF("omhttpfs: Append fail HTTP %ld: %s\n", response_code, pWrkrData->file); + return RS_RET_FALSE; + } + + iRet = httpfs_create_file(pWrkrData, buf); + if (iRet == RS_RET_OK) { + DBGPRINTF("omhttpfs: Create file success: %s\n", pWrkrData->file); + return RS_RET_OK; + } + + curl_easy_getinfo(pWrkrData->curl, CURLINFO_RESPONSE_CODE, &response_code); + if (response_code == 201) { + DBGPRINTF("omhttpfs: Create file success HTTP 201: %s\n", pWrkrData->file); + return RS_RET_OK; + } + + if (response_code == 500) { + DBGPRINTF("omhttpfs: Create file failed HTTP %ld: %s\n", response_code, pWrkrData->file); + httpfs_parse_exception(pWrkrData->reply, pWrkrData->replyLen, &jre); + if (!strncmp(jre.exception, HTTPFS_FILEALREADYEXISTSEXCEPTION, strlen(HTTPFS_FILEALREADYEXISTSEXCEPTION))) { + /* file exists, go to append */ + DBGPRINTF("omhttpfs: File already exists, append again: %s\n", pWrkrData->file); + + iRet = httpfs_append_file(pWrkrData, buf); + if (iRet == RS_RET_OK) { + DBGPRINTF("omhttpfs: Re-Append success: %s\n", pWrkrData->file); + return RS_RET_OK; + } else { + DBGPRINTF("omhttpfs: Re-Append failed: %s\n", pWrkrData->file); + /* error + exit */ + } + + } else { + DBGPRINTF("omhttpfs: Create file failed: %s %s\n", pWrkrData->file, pWrkrData->reply); + } + } else { + DBGPRINTF("omhttpfs: Create file failed: %s %s\n", pWrkrData->file, pWrkrData->reply); + } + + return RS_RET_FALSE; +} + + +BEGINinitConfVars + CODESTARTinitConfVars +ENDinitConfVars + + +BEGINcreateInstance +CODESTARTcreateInstance + DBGPRINTF("omhttpfs: createInstance\n"); +ENDcreateInstance + + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance + DBGPRINTF("omhttpfs: createWrkrInstance\n"); + pWrkrData->curl = NULL; + iRet = httpfs_init_curl(pWrkrData, pWrkrData->pData); + DBGPRINTF("omhttpfs: createWrkrInstance,pData %p/%p, pWrkrData %p\n", + pData, pWrkrData->pData, pWrkrData); +ENDcreateWrkrInstance + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURERepeatedMsgReduction) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +BEGINfreeInstance +CODESTARTfreeInstance + free(pData->file); + free(pData->tplName); + free(pData->host); + free(pData->user); +ENDfreeInstance + + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance + free(pWrkrData->file); + + if(pWrkrData->curl) { + curl_easy_cleanup(pWrkrData->curl); + pWrkrData->curl = NULL; + } +ENDfreeWrkrInstance + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + DBGPRINTF("OmHTTPFS\n"); + DBGPRINTF("Version: %s\n", OMHTTPFS_VERSION); + DBGPRINTF("\tHost: %s\n", pData->host); + DBGPRINTF("\tPort: %d\n", pData->port); + DBGPRINTF("\tUser: %s\n", pData->user); + DBGPRINTF("\tFile: %s\n", pData->file); +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume + DBGPRINTF("omhttpfs: tryResume called\n"); + /* TODO: test networking */ + iRet = RS_RET_OK; +ENDtryResume + +/** +* Do Action +*/ +BEGINdoAction +CODESTARTdoAction + DBGPRINTF("omhttpfs: doAction\n"); + /* dynamic file name */ + if (pWrkrData->pData->isDynFile) { + pWrkrData->file = ustrdup(ppString[1]); + } else { + pWrkrData->file = ustrdup(pWrkrData->pData->file); + } + + /* ppString[0] -> log content */ + iRet = httpfs_log(pWrkrData, ppString[0]); + + if(iRet != RS_RET_OK) { + DBGPRINTF("omhttpfs: error writing httpfs, suspending\n"); + iRet = RS_RET_SUSPENDED; + } +ENDdoAction + + + +/** + * Set default parameters + * + * @param instanceData *pData + * @return void + */ +static void +setInstParamDefaults(instanceData *pData) +{ + pData->host = (uchar*) strdup(OMHTTPFS_DEFAULT_HOST); + pData->port = OMHTTPFS_DEFAULT_PORT; + pData->user = (uchar*) strdup(OMHTTPFS_DEFAULT_USER); + pData->https = 0; + + pData->file = NULL; + pData->isDynFile = 0; + pData->tplName = NULL; +} + + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; + uchar *tplToUse; +CODESTARTnewActInst + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CHKiRet(createInstance(&pData)); + setInstParamDefaults(pData); + + for(i = 0 ; i < actpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(actpblk.descr[i].name, "host")) { + pData->host = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(actpblk.descr[i].name, "port")) { + pData->port = (int) pvals[i].val.d.n; + } else if(!strcmp(actpblk.descr[i].name, "user")) { + pData->user = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + + } else if(!strcmp(actpblk.descr[i].name, "https")) { + pData->https = pvals[i].val.d.n ? 1 : 0; + + } else if(!strcmp(actpblk.descr[i].name, "file")) { + pData->file = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL); + + } else if(!strcmp(actpblk.descr[i].name, "isdynfile")) { + pData->isDynFile = pvals[i].val.d.n ? 1 : 0; + + } else if(!strcmp(actpblk.descr[i].name, "template")) { + pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else { + DBGPRINTF("omhttpfs: program error, non-handled param '%s'\n", actpblk.descr[i].name); + } + } + if(pData->file == NULL) { + /* Note: this is primarily to make clang static analyzer happy, as we + * request via pblk that file is a mandatory parameter. However, this is + * also a guard against something going really wrong... + */ + LogError(0, RS_RET_INTERNAL_ERROR, "omhttpfs: file is not set " + "[this should not be possible]\n"); + ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); + } + if(pData->user == NULL || pData->user[0] == '\0') { + pData->user = ustrdup((uchar*) OMHTTPFS_DEFAULT_USER); + } + if(pData->host == NULL || pData->host[0] == '\0') { + pData->host = ustrdup((uchar*) OMHTTPFS_DEFAULT_HOST); + } + + if (pData->isDynFile) { + CODE_STD_STRING_REQUESTparseSelectorAct(2) + + CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->file), OMSR_NO_RQD_TPL_OPTS)); + } else { + CODE_STD_STRING_REQUESTparseSelectorAct(1) + } + + tplToUse = ustrdup((pData->tplName == NULL) ? (uchar* ) "RSYSLOG_FileFormat" : pData->tplName); + iRet = OMSRsetEntry(*ppOMSR, 0, tplToUse, OMSR_NO_RQD_TPL_OPTS); + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + + +NO_LEGACY_CONF_parseSelectorAct + + +/** +* Module Exit +*/ +BEGINmodExit +CODESTARTmodExit + /* */ + curl_global_cleanup(); + + /* release what we no longer need */ + objRelease(datetime, CORE_COMPONENT); + objRelease(glbl, CORE_COMPONENT); + +ENDmodExit + +/** +* Query Entry Point +*/ +BEGINqueryEtryPt +CODESTARTqueryEtryPt + CODEqueryEtryPt_STD_OMOD_QUERIES + CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES + CODEqueryEtryPt_STD_OMOD8_QUERIES + CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES +ENDqueryEtryPt + + +/** +* Module Init +*/ +BEGINmodInit() +CODESTARTmodInit +INITLegCnfVars + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + /* tell which objects we need */ + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + + if (curl_global_init(CURL_GLOBAL_ALL) != 0) { + LogError(0, RS_RET_OBJ_CREATION_FAILED, "CURL fail. -httpfs module init failed"); + ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); + } + + DBGPRINTF("omhttpfs version %s is initializing\n", OMHTTPFS_VERSION); + +ENDmodInit diff --git a/contrib/omrabbitmq/Makefile.am b/contrib/omrabbitmq/Makefile.am new file mode 100644 index 0000000..4c882f0 --- /dev/null +++ b/contrib/omrabbitmq/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = omrabbitmq.la + +omrabbitmq_la_SOURCES = omrabbitmq.c +omrabbitmq_la_CPPFLAGS = $(RABBITMQ_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +omrabbitmq_la_LDFLAGS = -module -avoid-version +omrabbitmq_la_LIBADD = $(RABBITMQ_LIBS) + +EXTRA_DIST = diff --git a/contrib/omrabbitmq/Makefile.in b/contrib/omrabbitmq/Makefile.in new file mode 100644 index 0000000..7765692 --- /dev/null +++ b/contrib/omrabbitmq/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omrabbitmq +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +omrabbitmq_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_omrabbitmq_la_OBJECTS = omrabbitmq_la-omrabbitmq.lo +omrabbitmq_la_OBJECTS = $(am_omrabbitmq_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omrabbitmq_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(omrabbitmq_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omrabbitmq_la_SOURCES) +DIST_SOURCES = $(omrabbitmq_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omrabbitmq.la +omrabbitmq_la_SOURCES = omrabbitmq.c +omrabbitmq_la_CPPFLAGS = $(RABBITMQ_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +omrabbitmq_la_LDFLAGS = -module -avoid-version +omrabbitmq_la_LIBADD = $(RABBITMQ_LIBS) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omrabbitmq/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omrabbitmq/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omrabbitmq.la: $(omrabbitmq_la_OBJECTS) $(omrabbitmq_la_DEPENDENCIES) $(EXTRA_omrabbitmq_la_DEPENDENCIES) + $(AM_V_CCLD)$(omrabbitmq_la_LINK) -rpath $(pkglibdir) $(omrabbitmq_la_OBJECTS) $(omrabbitmq_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omrabbitmq_la-omrabbitmq.lo: omrabbitmq.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omrabbitmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omrabbitmq_la-omrabbitmq.lo -MD -MP -MF $(DEPDIR)/omrabbitmq_la-omrabbitmq.Tpo -c -o omrabbitmq_la-omrabbitmq.lo `test -f 'omrabbitmq.c' || echo '$(srcdir)/'`omrabbitmq.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omrabbitmq_la-omrabbitmq.Tpo $(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omrabbitmq.c' object='omrabbitmq_la-omrabbitmq.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omrabbitmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omrabbitmq_la-omrabbitmq.lo `test -f 'omrabbitmq.c' || echo '$(srcdir)/'`omrabbitmq.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omrabbitmq/omrabbitmq.c b/contrib/omrabbitmq/omrabbitmq.c new file mode 100644 index 0000000..16c69ca --- /dev/null +++ b/contrib/omrabbitmq/omrabbitmq.c @@ -0,0 +1,1381 @@ +/* omrabbitmq.c + * + * This output plugin enables rsyslog to send messages to the RabbitMQ. + * + * Copyright 2012-2013 Vaclav Tomec + * Copyright 2014 Rainer Gerhards + * Copyright 2022 Hamid Maadani + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Vaclav Tomec + * <vaclav.tomec@gmail.com> + * + * TLS & AMQP heartbeat support added by: + * Hamid Maadani + * <hamid@dexo.tech> + * + */ +#include "config.h" +#include <pthread.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <time.h> +#include <sys/time.h> + +#include "rsyslog.h" +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "debug.h" +#include "datetime.h" +#include "rsconf.h" + +#include <sys/socket.h> + +#include "amqp.h" +#include "amqp_framing.h" +#include "amqp_tcp_socket.h" +#include "amqp_ssl_socket.h" +#if (AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR < 4) +#error "rabbitmq-c version must be >= 0.4.0" +#endif + +#define RABBITMQ_CHANNEL 1 + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP +MODULE_CNFNAME("omrabbitmq") + +/* + * internal structures + */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(datetime) + +static int instance_counter = 0; +static int mode_test = 0; + +typedef struct { + char *host; /* rabbitmq server fqdn or IP */ + int port; /* rabbitmq server port */ +} server_t; + +typedef struct { + server_t s; /* rabbitmq server */ + int failures; /* rabbitmq server failures */ +} server_wrk_t; + + +typedef struct { + time_t return_check_interval; /* time interval between usual server health checks */ + time_t half_return_check_interval; /* for computing */ + time_t quick_oscillation_interval; /* time interval below which the service is not stable */ + int quick_oscillation_max; /* number of quick oscillation after which the connection is kept on backup */ + time_t graceful_interval; /* time interval the connection is kept on backup after which the usual server + * check restarts */ + int quick_oscillation_count; /* current number of simultaneous quick oscillation detected */ +} recover_t; + +typedef struct _instanceData { + /* here you need to define all action-specific data. A record of type + * instanceData will be handed over to each instance of the action. Keep + * in mind that there may be several invocations of the same type of action + * inside rsyslog.conf, and this is what keeps them apart. Do NOT use + * static data for this! + */ + amqp_bytes_t exchange; /* exchange to send message to */ + + amqp_bytes_t routing_key; /* fixed routing_key to use */ + uchar *routing_key_template; /* routing_key template */ + int idx_routing_key_template; /* routing_key template index in doAction tab */ + + sbool populate_properties; /* populates message properties */ + int delivery_mode; /* delivery mode transient or persistent message */ + amqp_bytes_t expiration; /* message expiration */ + + uchar *body_template; /* body template */ + int idx_body_template; /* body template index in doAction tab */ + + amqp_basic_properties_t amqp_props_tpl_type; /* */ + char *content_type; /* */ + amqp_basic_properties_t amqp_props_plaintext; /* */ + + char *exchange_type; /* */ + int durable; /* */ + int auto_delete; /* */ + + int iidx; + int nbWrkr; + + server_t server1; /* first rabbitmq server */ + server_t server2; /* second rabbitmq server */ + + char *vhost; /* rabbitmq server vhost */ + char *user; /* rabbitmq username */ + char *password; /* rabbitmq username's password */ + + int ssl; /* should amqp connection be made over TLS? */ + int initOpenSSL; /* should rabbitmq-c initialize OpenSSL? */ + int verifyPeer; /* should peer be verified for TLS? */ + int verifyHostname; /* should hostname be verified for TLS? */ + int heartbeat; /* AMQP heartbeat interval in seconds (0 means disabled, which is default) */ + char *caCert; /* CA certificate to be used for TLS connection */ + + recover_t recover_policy; + +} instanceData; + +typedef struct wrkrInstanceData { + amqp_connection_state_t a_conn; /* amqp connection */ + + int connected; + int channel_opened; + + pthread_t thread; /* */ + short thread_running; /* */ + pthread_mutex_t send_mutex; /* */ + pthread_cond_t cond; /* */ + + rsRetVal state; /* state of the connection */ + + server_wrk_t serverPrefered; /* usual rabbitmq server */ + server_wrk_t serverBackup; /* backup rabbitmq server */ + server_wrk_t *serverActive; /* active rabbitmq server */ + + instanceData *pData; + + recover_t recover_policy; + time_t last_failback; + + int iidx; + int widx; + int go_on; +} wrkrInstanceData_t; + +typedef struct _msg2amqp_props_ { + propid_t id; + const char *name; + amqp_bytes_t *standardprop; + int flag; +} msg2amqp_props_t; + +/* tables for interfacing with the v6 config system */ +/* action (instance) parameters */ +static struct cnfparamdescr actpdescr[] = { + { "host", eCmdHdlrString, 0 }, + { "port", eCmdHdlrInt, 0 }, + { "virtual_host", eCmdHdlrGetWord, 0 }, + { "heartbeat_interval", eCmdHdlrNonNegInt, 0 }, + { "user", eCmdHdlrGetWord, 0 }, + { "password", eCmdHdlrGetWord, 0 }, + { "ssl", eCmdHdlrBinary, 0 }, + { "init_openssl", eCmdHdlrBinary, 0 }, + { "verify_peer", eCmdHdlrBinary, 0 }, + { "verify_hostname", eCmdHdlrBinary, 0 }, + { "ca_cert", eCmdHdlrGetWord, 0 }, + { "exchange", eCmdHdlrGetWord, 0 }, + { "routing_key", eCmdHdlrGetWord, 0 }, + { "routing_key_template", eCmdHdlrGetWord, 0 }, + { "delivery_mode", eCmdHdlrGetWord, 0 }, + { "expiration", eCmdHdlrNonNegInt, 0 }, + { "populate_properties", eCmdHdlrBinary, 0 }, + { "body_template", eCmdHdlrGetWord, 0 }, + { "content_type", eCmdHdlrGetWord, 0 }, + { "recover_policy", eCmdHdlrString, 0 }, + { "exchange_type", eCmdHdlrGetWord, 0}, + { "durable", eCmdHdlrBinary, 0}, + { "auto_delete", eCmdHdlrBinary, 0}, +}; +static struct cnfparamblk actpblk = + { + CNFPARAMBLK_VERSION, + sizeof(actpdescr)/sizeof(struct cnfparamdescr), + actpdescr + }; + +static amqp_bytes_t cstring_bytes(const char *str) +{ + return str ? amqp_cstring_bytes(str) : amqp_empty_bytes; +} + +/* Initialize recover structure from the configuration string + */ +static void init_recover(recover_t *fb, char *str) +{ + time_t value[4] = { 0, 0, 0, 0 }; + + if (str && *str){ + int i = -1; + do { + value[++i] = strtoul(str, &str, 10); + if (*str) str++; + } while (i < 3 && value[i] && *str); + } + + fb->return_check_interval = (value[0]) ? value[0] : 60; + fb->half_return_check_interval = fb->return_check_interval / 2; + fb->quick_oscillation_interval = (value[1]) ? value[1] : (fb->return_check_interval / 10); + fb->quick_oscillation_max = (value[2]) ? (int)(value[2]) : 3; + fb->graceful_interval = (value[3]) ? value[3] : (fb->return_check_interval * 10) - + fb->half_return_check_interval; + fb->quick_oscillation_count = 0; +} + +/* this method compute the delay before next reconnection attempt according + */ +static unsigned long next_check(recover_t *fb, time_t last_failback) +{ + time_t now = time(NULL); + srandom(now); + + if (now - last_failback < fb->quick_oscillation_interval) { + /* quick oscillation detected */ + fb->quick_oscillation_count++; + + if (fb->quick_oscillation_count > fb->quick_oscillation_max) { + /* too much oscillation inserting a graceful sleep */ + fb->quick_oscillation_count = 0; + return fb->graceful_interval + fb->return_check_interval * random() / RAND_MAX; + } + } else + fb->quick_oscillation_count = 0; + + /* returning a standard delay between 0,5 and 1,5 * return_check_interval */ + return fb->half_return_check_interval + fb->return_check_interval * random() / RAND_MAX; +} + +/* authenticate to rabbitmq server and set connection parameter according to rsyslog configuration + */ +static int amqp_authenticate(wrkrInstanceData_t *self, amqp_connection_state_t a_conn) +{ + amqp_rpc_reply_t ret; + + /* define the frame size */ + int frame_size = (glbl.GetMaxLine(runConf)<130000) ? 131072 : (glbl.GetMaxLine(runConf)+1072); + + /* authenticate */ + ret = amqp_login(a_conn, (char const *)self->pData->vhost, 1, frame_size, self->pData->heartbeat, + AMQP_SASL_METHOD_PLAIN, self->pData->user, self->pData->password); + + if (ret.reply_type != AMQP_RESPONSE_NORMAL) + { + LogError(0, RS_RET_RABBITMQ_LOGIN_ERR, "omrabbitmq module %d/%d: login to AMQP " + "server %s failed. (%d / %s)", + self->iidx, self->widx, self->serverActive->s.host, ret.reply_type, + amqp_error_string2(ret.library_error)); + return 0; + } + + /* open the communication channel */ + amqp_channel_open(a_conn, 1); + + if (amqp_get_rpc_reply(a_conn).reply_type != AMQP_RESPONSE_NORMAL) + { + LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, "omrabbitmq module %d/%d: open channel failed.", + self->iidx, self->widx); + return 0; + } + + if (self->pData->exchange_type) { + /* we declare the exchange according to specifications */ + amqp_table_t props = { 0, NULL }; + #if (AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR < 6) + amqp_exchange_declare(a_conn, 1, self->pData->exchange, cstring_bytes(self->pData->exchange_type), + 0, self->pData->durable, props); + #else + amqp_exchange_declare(a_conn, 1, self->pData->exchange, cstring_bytes(self->pData->exchange_type), + 0, self->pData->durable, self->pData->auto_delete, 0, props); + #endif + + if (amqp_get_rpc_reply(a_conn).reply_type != AMQP_RESPONSE_NORMAL) + { + /* if a problem occurs on declaring the exchange we receive a channel_close with the + * error then we can log the error, respond a channel_close_ok and reopen it + * so we can work with the existing exchange. + */ + amqp_channel_close_ok_t chan_cls_ok; + amqp_channel_close_t *chan_cls = + (amqp_channel_close_t*)amqp_get_rpc_reply(a_conn).reply.decoded; + + if (amqp_get_rpc_reply(a_conn).reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION) { + LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, + "omrabbitmq module %d/%d: disconnected while exchange declare (%d)", + self->iidx, self->widx, amqp_get_rpc_reply(a_conn).library_error); + return 0; + } + + LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, + "omrabbitmq module %d/%d: exchange declare failed %.*s.", self->iidx, self->widx, + (int)chan_cls->reply_text.len, (char*)chan_cls->reply_text.bytes); + + chan_cls_ok.dummy = '\0'; + amqp_send_method(a_conn, 1, AMQP_CHANNEL_CLOSE_OK_METHOD, &chan_cls_ok); + + /* reopen the communication channel in case of error it should be close by server*/ + amqp_channel_open(a_conn, 1); + + if (amqp_get_rpc_reply(a_conn).reply_type != AMQP_RESPONSE_NORMAL) + { + LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, "omrabbitmq module %d/%d: " + "open channel failed.", self->iidx, self->widx); + return 0; + } + + } + } + /* release the buffers if possible */ + amqp_maybe_release_buffers(a_conn); + + return 1; +} + +/* This method establish a new connection + * @self pointer on the worker datas + * @server pointer on the server datas (preferred or backup) + * @return the connection state or NULL on error + */ +static amqp_connection_state_t tryConnection(wrkrInstanceData_t *self, server_t *server) +{ + int retconn = 0; + struct timeval delay; + delay.tv_sec = 1; + delay.tv_usec = 0; + amqp_socket_t *sockfd = NULL; + + amqp_connection_state_t a_conn = amqp_new_connection(); + if (a_conn) { + if (self->pData->ssl) { + if (!self->pData->initOpenSSL) { + // prevent OpenSSL double initialization + amqp_set_initialize_ssl_library(0); + } + sockfd = amqp_ssl_socket_new(a_conn); + } else { + sockfd = amqp_tcp_socket_new(a_conn); + } + } + + if (sockfd) + { + if (self->pData->ssl) { +#if (AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR < 8) + amqp_ssl_socket_set_verify(sockfd, self->pData->verifyPeer); +#else + amqp_ssl_socket_set_verify_peer(sockfd, self->pData->verifyPeer); + amqp_ssl_socket_set_verify_hostname(sockfd, self->pData->verifyHostname); +#endif + if (self->pData->caCert) { + amqp_ssl_socket_set_cacert(sockfd, self->pData->caCert); + } + } + + LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, + "omrabbitmq module %d/%d: server %s port %d.", self->iidx, self->widx, + server->host, server->port); + + #if defined(_AIX) + retconn = amqp_socket_open(sockfd, server->host, server->port); + #else + retconn = amqp_socket_open_noblock(sockfd, (const char*)server->host, server->port, &delay); + #endif + } + + if (retconn == AMQP_STATUS_OK && amqp_authenticate(self, a_conn)) + return a_conn; + + /* the connection failed so free it and return NULL */ + amqp_connection_close(a_conn, 200); + amqp_destroy_connection(a_conn); +#if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) + if (self->pData->ssl && self->pData->initOpenSSL) { + amqp_uninitialize_ssl_library(); + } +#endif + + return NULL; +} + +static int manage_connection(wrkrInstanceData_t *self, amqp_frame_t *pFrame) +{ + int result; + + pthread_mutex_unlock(&self->send_mutex); + + do { + if (self->serverActive == &self->serverBackup) + { + amqp_connection_state_t new_conn; + struct timeval delay; + + /* The worker is connected to the backup server. + * next_check function compute the delay before trying to recover + * the connection to the preferred server according to recover_policy + */ + delay.tv_sec = next_check(&self->recover_policy, self->last_failback); + delay.tv_usec = 0; + + result = amqp_simple_wait_frame_noblock(self->a_conn, pFrame, &delay); + + /* if connected to backup server then check if usual server is alive. + * if so then disconnect from backup */ + if (result == AMQP_STATUS_TIMEOUT && + (new_conn = tryConnection(self, + &(self->serverPrefered.s))) + != NULL) { + /* connection is re-established to preferred server so + * swap connections */ + amqp_connection_state_t old_conn = self->a_conn; + + /* now lock to avoid message publishing. */ + pthread_mutex_lock(&self->send_mutex); + self->a_conn = new_conn; + self->serverActive = &self->serverPrefered; + self->serverActive->failures = 0; + pthread_mutex_unlock(&self->send_mutex); + /* back to unlock mode */ + + DBGPRINTF("omrabbitmq module %d: reconnects to usual server.\n", + self->iidx); + amqp_connection_close(old_conn, 200); + amqp_destroy_connection(old_conn); +#if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) + if (self->pData->ssl && self->pData->initOpenSSL) { + amqp_uninitialize_ssl_library(); + } +#endif + } + + } else { + + result = amqp_simple_wait_frame(self->a_conn, pFrame); + + } + } while(result == AMQP_STATUS_TIMEOUT); + + /* now lock the mutex to avoid message publishing. */ + pthread_mutex_lock(&self->send_mutex); + + return result; +} + +static void send_connection_close(amqp_connection_state_t state) { + amqp_connection_close_t *req = malloc(sizeof(amqp_connection_close_t)); + memset(req, 0, sizeof(amqp_connection_close_t)); + req->reply_code = 200; + req->reply_text.bytes = (void*)"200"; + req->reply_text.len = 3; + req->class_id = (uint16_t)(AMQP_CONNECTION_CLOSE_METHOD >> 16); + req->method_id = (uint16_t)(AMQP_CONNECTION_CLOSE_METHOD & 0xFFFF); + amqp_send_method(state, 0, AMQP_CONNECTION_CLOSE_METHOD, req); + free(req); +} + +static void send_channel_close(amqp_connection_state_t state, amqp_channel_t ch) { + amqp_channel_close_t *req = malloc(sizeof(amqp_channel_close_t)); + memset(req, 0, sizeof(amqp_channel_close_t)); + req->reply_code = 200; + req->reply_text.bytes = (void*)"200"; + req->reply_text.len = 3; + req->class_id = (uint16_t)(AMQP_CHANNEL_CLOSE_METHOD >> 16); + req->method_id = (uint16_t)(AMQP_CHANNEL_CLOSE_METHOD & 0xFFFF); + amqp_send_method(state, ch, AMQP_CHANNEL_CLOSE_METHOD, req); + free(req); +} + +static void send_connection_close_ok(amqp_connection_state_t state) { + amqp_connection_close_ok_t *req = malloc(sizeof(amqp_connection_close_ok_t)); + memset(req, 0, sizeof(amqp_connection_close_ok_t)); + req->dummy = '\0'; + amqp_send_method(state, 0, AMQP_CONNECTION_CLOSE_OK_METHOD, req); + free(req); +} + +static void send_channel_close_ok(amqp_connection_state_t state, amqp_channel_t ch) { + amqp_channel_close_ok_t *req = malloc(sizeof(amqp_channel_close_ok_t)); + memset(req, 0, sizeof(amqp_channel_close_ok_t)); + req->dummy = '\0'; + amqp_send_method(state, ch, AMQP_CHANNEL_CLOSE_OK_METHOD, req); + free(req); +} + +/* run_connection_routine is the thread monitoring of the rabbitmq connection. + * This method manage reconnection to preferred and backup servers apply the recover_policy + */ +static void* run_connection_routine(void* arg) +{ + wrkrInstanceData_t *self = (wrkrInstanceData_t *) arg; + amqp_frame_t frm; + int result; + self->connected = 0; + self->channel_opened = 0; + rsRetVal state_out = RS_RET_SUSPENDED; + + dbgSetThrdName((uchar*)"amqp connection"); + + /* now lock to avoid message publishing during part of the thread loop */ + pthread_mutex_lock(&self->send_mutex); + + self->thread_running = 1; + + self->state = RS_RET_OK; + + srSleep(0,100); + + DBGPRINTF("omrabbitmq module %d/%d: connection thread started\n", self->iidx, self->widx); + + int go_on = self->go_on; + + while (go_on) // this loop is used to reconnect on connection failure + { + if (self->a_conn != NULL) + { + amqp_connection_close(self->a_conn, 200); + amqp_destroy_connection(self->a_conn); +#if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) + if (self->pData->ssl && self->pData->initOpenSSL) { + amqp_uninitialize_ssl_library(); + } +#endif + } + + self->a_conn = NULL; + + if (!self->go_on) + { + go_on = 0; + state_out = RS_RET_DISABLE_ACTION; + continue; /* lets go back to wile (go_on) and leave cleanly */ + } + + if (self->serverActive == &self->serverBackup) { + self->serverBackup.failures = 0; + self->serverPrefered.failures = 0; + self->serverActive = &self->serverPrefered; + } + + do { /* this loop tries 3 times per server before switching servers */ + if ((self->a_conn = tryConnection(self, &(self->serverActive->s))) != NULL) { + self->serverActive->failures = 0; + } else { + /* set 1 second before retry */ + struct timeval delay; + + delay.tv_sec = 1; + delay.tv_usec = 0; + + self->serverActive->failures++; + + /* if 3 tries */ + if (self->serverActive->failures == 3) { + + if (!self->serverBackup.s.host || self->serverBackup.failures == 3) + { + LogError(0, RS_RET_RABBITMQ_CONN_ERR, "omrabbitmq module connection " + "failed 3 times on each server."); + } + + if (self->serverActive == &self->serverBackup) { + self->serverBackup.failures = 0; + self->serverPrefered.failures = 0; + self->serverActive = &self->serverPrefered; + } else { + /* on usual server switch to backup server */ + if (self->serverBackup.s.host) + self->serverActive = &self->serverBackup; + else + self->serverPrefered.failures = 0; + } + /* set 5 second before new round trip */ + delay.tv_sec = 5; + } + select(0,NULL,NULL,NULL,&delay); + } + } + while (self->a_conn == NULL && self->go_on); + + if (!self->go_on) + { + go_on = 0; + state_out = RS_RET_DISABLE_ACTION; + continue; /* lets go back to wile (go_on) and leave cleanly */ + } + + /* signal that the thread is started */ + pthread_cond_signal(&self->cond); + + self->connected = 1; + self->channel_opened = 1; + + DBGPRINTF("omrabbitmq module %d: connected.\n", self->iidx); + + self->state = RS_RET_OK; + + if (self->serverActive == &self->serverBackup) + self->last_failback = time(NULL); + + while (self->connected) // this loop is used to manage an established connection + { + + result = manage_connection(self, &frm); + + switch (result) + { + case AMQP_STATUS_NO_MEMORY: + LogError(0, RS_RET_OUT_OF_MEMORY, "omrabbitmq module %d/%d: no memory " + ": aborting module.", self->iidx, self->widx); + go_on = 0; /* non recoverable error let's go out */ + self->connected = 0; + state_out = RS_RET_DISABLE_ACTION; + break; + case AMQP_STATUS_BAD_AMQP_DATA: + LogError(0, RS_RET_RABBITMQ_CONN_ERR, "omrabbitmq module %d/%d: bad " + "data received : reconnect.", self->iidx, self->widx); + self->connected = 0; + break; + case AMQP_STATUS_SOCKET_ERROR: + LogError(0, RS_RET_RABBITMQ_CONN_ERR, "omrabbitmq module %d/%d: Socket" + " error : reconnect.", self->iidx, self->widx); + self->connected = 0; + break; + case AMQP_STATUS_CONNECTION_CLOSED: + LogError(0, RS_RET_OUT_OF_MEMORY, "omrabbitmq module %d/%d: Connection" + " closed : reconnect.", self->iidx, self->widx); + self->connected = 0; + break; + case AMQP_STATUS_OK: + /* perhaps not a frame type so ignore it */ + if (frm.frame_type == AMQP_FRAME_METHOD) + { + amqp_method_number_t id = frm.payload.method.id; + /* now handle frames from the server */ + switch (id) + { + case AMQP_CONNECTION_CLOSE_OK_METHOD: + + /* We asked to close the connection and server has responded to us */ + self->connected = 0; + go_on = 0; + break; + + case AMQP_CHANNEL_CLOSE_OK_METHOD: + + /* We asked to close the channel and server has responded to us */ + send_connection_close(self->a_conn); + self->channel_opened = 0; + break; + + case AMQP_CHANNEL_CLOSE_METHOD: + + /* the server wants to close the channel then the connection */ + LogMsg(0, RS_RET_OK, LOG_WARNING,"omrabbitmq module %d/%d: " + "Close Channel Received (%X).", self->iidx, self->widx, id); + /* answer the server request & send the method */ + send_channel_close_ok(self->a_conn, frm.channel); + self->channel_opened = 0; + break; + + case AMQP_CONNECTION_CLOSE_METHOD: + + /* the server want to close the connection */ + LogMsg(0, RS_RET_OK, LOG_WARNING, "omrabbitmq module %d/%d: " + "Close Connection Received (%X).", self->iidx, self->widx, id); + /* answer the server request */ + send_connection_close_ok(self->a_conn); + self->connected = 0; + break; + + default : + + LogMsg(0, RS_RET_OK, LOG_WARNING, "omrabbitmq module %d/%d: " + "Unmanaged amqp method received (%X) : ignored.", + self->iidx, self->widx, id); + } /* switch (frm.payload.method.id) */ + } /* if (frm.frame_type == AMQP_FRAME_METHOD) */ + break; + } /* switch (result) */ + } + } + self->state = state_out; + + /* The core ask to die so let's disconnect */ + if (self->a_conn != NULL) + { + if (self->channel_opened) + amqp_channel_close(self->a_conn, 1, 200); + if (self->connected) + amqp_connection_close(self->a_conn, 200); + amqp_destroy_connection(self->a_conn); + self->a_conn = NULL; +#if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) + if (self->pData->ssl && self->pData->initOpenSSL) { + amqp_uninitialize_ssl_library(); + } +#endif + } + + self->thread_running = 0; + + /* Finishing by unlocking before the end of the thread */ + pthread_mutex_unlock(&self->send_mutex); + + /* Now notify the worker that this thread is stopping */ + pthread_cond_signal(&self->cond); + + return NULL; +} + +/* ============================================================================================ + * Main thread + * ============================================================================================ + */ + +static rsRetVal startAMQPConnection(wrkrInstanceData_t *self) +{ + DEFiRet; + pthread_mutex_lock(&self->send_mutex); + self->go_on = 1; + if (self->thread_running == 0) + { + if (!pthread_create(&self->thread, NULL, run_connection_routine, self)) + { + pthread_cond_wait(&self->cond,&self->send_mutex); + iRet = self->state; + }else{ + iRet = RS_RET_DISABLE_ACTION; + } + } + pthread_mutex_unlock(&self->send_mutex); + RETiRet; +} + +static void closeAMQPConnection(wrkrInstanceData_t *self) +{ + if (!self || !self->a_conn) return; + + void *ret; + + /* Now locks to allow exclusive access to sock */ + pthread_mutex_lock(&self->send_mutex); + + self->go_on = 0; + + /* send the method */ + if (self->a_conn) + { + if (self->channel_opened){ + send_channel_close(self->a_conn, 0); + } else { + send_connection_close(self->a_conn); + } + } + /* Release the lock */ + pthread_mutex_unlock(&self->send_mutex); + + /* Now wvait for the thread to stop */ + pthread_join(self->thread, &ret); +} + +/* + * Report general error + */ +static int manage_error(int x, char const *context) +{ + int retVal = 0; // false + + if (x < 0) { + #if (AMQP_VERSION_MINOR >= 4) + const char *errstr = amqp_error_string2(-x); + LogError(0, RS_RET_ERR, "omrabbitmq: %s: %s", context, errstr); + #else + char *errstr = amqp_error_string(-x); + LogError(0, RS_RET_ERR, "omrabbitmq: %s: %s", context, errstr); + free(errstr); + #endif + retVal = 1; // true + } + + return retVal; +} + +static rsRetVal publishRabbitMQ(wrkrInstanceData_t *self, amqp_bytes_t exchange, + amqp_bytes_t routing_key, amqp_basic_properties_t *p_amqp_props, + amqp_bytes_t body_bytes) +{ + DEFiRet; + /* locks to allow exclusive access to connection */ + if (mode_test > 0) { + struct timeval tv; + tv.tv_sec = mode_test/1000; + tv.tv_usec = mode_test%1000 * 1000; + select(0, NULL, NULL, NULL, &tv); + } + + pthread_mutex_lock(&self->send_mutex); + + if (self->state != RS_RET_OK) + ABORT_FINALIZE(self->state); + + if (!self->a_conn){ + ABORT_FINALIZE(RS_RET_RABBITMQ_CONN_ERR); + } + + if (manage_error(amqp_basic_publish(self->a_conn, 1, exchange, routing_key, + 0, 0, p_amqp_props, body_bytes), "amqp_basic_publish")) { + /* error already notified */ + FINALIZE; + } + +finalize_it: + /* release exclusive access to connection */ + pthread_mutex_unlock(&self->send_mutex); + RETiRet; +} + +BEGINdoAction + int iLen; +CODESTARTdoAction + /* The first element is a smsg_t pointer */ + smsg_t **pMsg = (smsg_t **)pMsgData; + smsg_t *msg = pMsg[0]; + + amqp_bytes_t body_bytes; + amqp_basic_properties_t *amqp_props_msg; + + if (!pWrkrData->pData->idx_body_template) + { + /* No body template so send it as rawmsg */ + getRawMsg(msg, (uchar**)(&body_bytes.bytes), &iLen); + body_bytes.len = (size_t)iLen; + amqp_props_msg = &pWrkrData->pData->amqp_props_plaintext; + } + else + { + /* we have a body template */ + body_bytes = cstring_bytes((char*)ppString[pWrkrData->pData->idx_body_template]); + amqp_props_msg = &pWrkrData->pData->amqp_props_tpl_type; + } + + if (pWrkrData->pData->populate_properties) { + /* populate amqp message properties */ + msgPropDescr_t pProp; + int i, custom = 0; + amqp_basic_properties_t amqp_props; + + memcpy(&amqp_props, amqp_props_msg, sizeof(amqp_basic_properties_t)); + + /* list and mapping of smsg to amqp properties */ + msg2amqp_props_t prop_list[] = { + { PROP_SYSLOGFACILITY_TEXT, "facility", NULL, 0 }, + { PROP_SYSLOGSEVERITY_TEXT, "severity", NULL, 0 }, + { PROP_HOSTNAME, "hostname", NULL, 0 }, + { PROP_FROMHOST, "fromhost", NULL, 0 }, + { PROP_SYSLOGTAG, NULL, &(amqp_props.app_id), AMQP_BASIC_APP_ID_FLAG } + }; + int len = sizeof(prop_list)/sizeof(msg2amqp_props_t); + uchar *val[sizeof(prop_list)/sizeof(msg2amqp_props_t)]; + rs_size_t valLen[sizeof(prop_list)/sizeof(msg2amqp_props_t)]; + unsigned short mustBeFreed[sizeof(prop_list)/sizeof(msg2amqp_props_t)]; + struct amqp_table_entry_t_ tab_entries[sizeof(prop_list)/sizeof(msg2amqp_props_t)]; + + amqp_props.headers.entries = tab_entries; + + amqp_props.timestamp = (uint64_t)datetime.syslogTime2time_t(&msg->tTIMESTAMP); + amqp_props._flags |= AMQP_BASIC_TIMESTAMP_FLAG; + + for (i=0; i<len; i++) + { + /* for each msg property in list get the value and initialize flags */ + pProp.id = prop_list[i].id; + valLen[i] = 0; + mustBeFreed[i] = 0; + val[i] = (uchar*)MsgGetProp(msg, NULL, &pProp, &(valLen[i]), &(mustBeFreed[i]), NULL); + if (val[i] && *val[i]) + { + if (prop_list[i].name) + { + /* custom amqp properties */ + tab_entries[custom].key = amqp_cstring_bytes(prop_list[i].name); + tab_entries[custom].value.kind = AMQP_FIELD_KIND_UTF8; + tab_entries[custom].value.value.bytes = amqp_cstring_bytes((char*)val[i]); + amqp_props._flags |= AMQP_BASIC_HEADERS_FLAG; + custom++; + } else { + /* standard amqp properties*/ + prop_list[i].standardprop->bytes = val[i]; + prop_list[i].standardprop->len = (size_t)valLen[i]; + amqp_props._flags |= prop_list[i].flag; + } + } + } + amqp_props.headers.num_entries = custom; + + /* CHKiRet could not be used because we need to release allocations */ + iRet = publishRabbitMQ(pWrkrData, pWrkrData->pData->exchange, + (pWrkrData->pData->routing_key_template)? + cstring_bytes((char*)ppString[pWrkrData->pData->idx_routing_key_template]) + : pWrkrData->pData->routing_key, + &amqp_props, body_bytes); + + for (i=0; i<len; i++) + if (mustBeFreed[i]) free(val[i]); + } + else + { + /* As CHKiRet could not be used earlier, iRet is directly used again */ + iRet = publishRabbitMQ(pWrkrData, pWrkrData->pData->exchange, + (pWrkrData->pData->routing_key_template)? + cstring_bytes((char*)ppString[pWrkrData->pData->idx_routing_key_template]) + : pWrkrData->pData->routing_key, + amqp_props_msg, body_bytes); + } + +ENDdoAction + +BEGINtryResume +CODESTARTtryResume + iRet = startAMQPConnection(pWrkrData); +ENDtryResume + +BEGINcreateInstance + void *env_var; +CODESTARTcreateInstance + if ((env_var = getenv("OMRABBITMQ_TEST")) != NULL) + mode_test = atoi(env_var); + + memset(pData, 0, sizeof(instanceData)); + pData->iidx = ++instance_counter; + pData->delivery_mode = 2; + pData->exchange_type = NULL; + pData->durable = 0; + pData->auto_delete = 1; + pData->ssl = 0; + pData->initOpenSSL = 0; + pData->verifyPeer = 0; + pData->verifyHostname = 0; + pData->caCert = NULL; + pData->heartbeat = 0; +ENDcreateInstance + +BEGINfreeInstance +CODESTARTfreeInstance + /* this is a cleanup callback. All dynamically-allocated resources + * in instance data must be cleaned up here. Prime examples are + * malloc()ed memory, file & database handles and the like. + */ + if (pData->exchange.bytes) free(pData->exchange.bytes); + if (pData->routing_key.bytes) free(pData->routing_key.bytes); + if (pData->routing_key_template) free(pData->routing_key_template); + if (pData->body_template) free(pData->body_template); + if (pData->expiration.bytes) free(pData->expiration.bytes); + if (pData->content_type) free(pData->content_type); + if (pData->vhost) free(pData->vhost); + if (pData->user) free(pData->user); + if (pData->password) free(pData->password); + if (pData->exchange_type) free(pData->exchange_type); + if (pData->server1.host) free(pData->server1.host); + if (pData->caCert) free(pData->caCert); +ENDfreeInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + /* use this to specify if select features are supported by this + * plugin. If not, the framework will handle that. Currently, only + * RepeatedMsgReduction ("last message repeated n times") is optional. + */ + if(eFeat == sFEATURERepeatedMsgReduction) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + /* permits to spit out some debug info */ + dbgprintf("omrabbitmq instance : %d\n", pData->iidx); + if (pData->server2.host) { + dbgprintf("\thost1='%s' \n", pData->server1.host); + dbgprintf("\tport1=%d\n", pData->server1.port); + dbgprintf("\thost2='%s' \n", pData->server2.host); + dbgprintf("\tport2=%d\n", pData->server2.port); + dbgprintf("\tfailback policy :"); + dbgprintf("\t\tusual server check interval=%ld s", + pData->recover_policy.return_check_interval); + dbgprintf("\t\tquick oscillation limit=%ld s", + pData->recover_policy.quick_oscillation_interval); + dbgprintf("\t\tmax number of oscillation=%d s", + pData->recover_policy.quick_oscillation_max); + dbgprintf("\t\tgraceful interval after quick oscillation detection=%ld s", + pData->recover_policy.graceful_interval); + }else{ + dbgprintf("\thost='%s' \n", pData->server1.host); + dbgprintf("\tport=%d\n", pData->server1.port); + } + dbgprintf("\tvirtual_host='%s'\n", pData->vhost); + dbgprintf("\tuser='%s'\n", pData->user == NULL ? "(not configured)" : pData->user); + dbgprintf("\tpassword=(%sconfigured)\n", pData->password == NULL ? "not " : ""); + dbgprintf("\tssl=%d\n", pData->ssl); + dbgprintf("\tinit_openssl=%d\n", pData->initOpenSSL); + dbgprintf("\tverify_peer=%d\n", pData->verifyPeer); + dbgprintf("\tverify_hostname=%d\n", pData->verifyHostname); + dbgprintf("\tca_cert='%s'\n", pData->caCert); + dbgprintf("\theartbeat_interval=%d\n", pData->heartbeat); + + dbgprintf("\texchange='%*s'\n", (int)pData->exchange.len, + (char*)pData->exchange.bytes); + dbgprintf("\trouting_key='%*s'\n", (int)pData->routing_key.len, + (char*) pData->routing_key.bytes); + dbgprintf("\trouting_key_template='%s'\n", pData->routing_key_template); + dbgprintf("\tbody_template='%s'\n", pData->body_template); + dbgprintf("\texchange_type='%s'\n", pData->exchange_type); + dbgprintf("\tauto_delete=%d\n", pData->auto_delete); + dbgprintf("\tdurable=%d\n", pData->durable); + dbgprintf("\tpopulate_properties=%s\n", (pData->populate_properties)?"ON":"OFF"); + dbgprintf((pData->delivery_mode == 1) ? "\tdelivery_mode=TRANSIENT\n": + "\tdelivery_mode=PERSISTENT\n"); + if (pData->expiration.len == 0) { + dbgprintf("\texpiration=UNLIMITED\n"); + }else{ + dbgprintf("\texpiration=%*s\n", + (int)pData->expiration.len, (char*) pData->expiration.bytes); + } +ENDdbgPrintInstInfo + +BEGINnewActInst + struct cnfparamvals *pvals; + int i; + char *host = NULL, *vhost= NULL, *user = NULL, *password = NULL, *recover = NULL; + int port = 0; + long long expiration = 0; +CODESTARTnewActInst + + if((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + CHKiRet(createInstance(&pData)); + + /* let read parameters */ + for(i = 0 ; i < actpblk.nParams ; ++i) { + if (!pvals[i].bUsed) + continue; + if (!strcmp(actpblk.descr[i].name, "host")) { + host = (char*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "recover_policy")) { + recover = es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "port")) { + port = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "virtual_host")) { + vhost = (char*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "user")) { + user = (char*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "password")) { + password = (char*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "ssl")) { + pData->ssl = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "ca_cert")) { + pData->caCert = (char*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "heartbeat_interval")) { + pData->heartbeat = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "init_openssl")) { + pData->initOpenSSL = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "verify_peer")) { + pData->verifyPeer = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "verify_hostname")) { + pData->verifyHostname = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "exchange")) { + pData->exchange = cstring_bytes(es_str2cstr(pvals[i].val.d.estr, NULL)); + } else if (!strcmp(actpblk.descr[i].name, "routing_key")) { + pData->routing_key = cstring_bytes(es_str2cstr(pvals[i].val.d.estr, NULL)); + } else if (!strcmp(actpblk.descr[i].name, "routing_key_template")) { + pData->routing_key_template = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "populate_properties")) { + pData->populate_properties = (sbool) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "delivery_mode")) { + char *temp = (char*)es_str2cstr(pvals[i].val.d.estr, NULL); + if (temp){ + if (!strcasecmp(temp, "TRANSIENT") || !strcmp(temp, "1")) { + pData->delivery_mode = 1; + } else { if (!strcasecmp(temp, "PERSISTENT") || !strcmp(temp, "2")) { + pData->delivery_mode = 2; + } else { + pData->delivery_mode = 0; + } } + free(temp); + } + } else if (!strcmp(actpblk.descr[i].name, "expiration")) { + expiration = pvals[i].val.d.n; + if (expiration > 0) { + char buf[40]; + snprintf(buf, 40, "%lld", expiration); + #ifndef __clang_analyzer__ + pData->expiration = cstring_bytes(strdup(buf)); + #endif + } + } else if (!strcmp(actpblk.descr[i].name, "body_template")) { + pData->body_template = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "content_type")) { + pData->content_type = es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "exchange_type")) { + pData->exchange_type = es_str2cstr(pvals[i].val.d.estr, NULL); + } else if (!strcmp(actpblk.descr[i].name, "auto_delete")) { + pData->auto_delete = (int) pvals[i].val.d.n; + } else if (!strcmp(actpblk.descr[i].name, "durable")) { + pData->durable = (int) pvals[i].val.d.n; + } else { + LogError(0, RS_RET_INVALID_PARAMS, + "omrabbitmq module %d: program error, non-handled param '%s'\n", + pData->iidx, actpblk.descr[i].name); + } + } + + /* let's check config validity */ + + if (host == NULL) { + LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d disabled: parameter " + "host must be specified", + pData->iidx); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + /* first if a template for routing_key is set let verify its existence */ + if (pData->routing_key_template && tplFind(ourConf, (char*)pData->routing_key_template, + strlen((char*)pData->routing_key_template)) == NULL) + { + LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d : template '%s'" + " used for routing key does not exist !", + pData->iidx, pData->routing_key_template); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + /* an exchange must be defined */ + if (pData->exchange.bytes == NULL) { + LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d disabled: parameter " + "exchange must be specified", + pData->iidx); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + /* a static or a template's routing_key must be defined */ + if (pData->routing_key.bytes == NULL && pData->routing_key_template == NULL) { + LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d disabled: " + "one of parameters routing_key or " + "routing_key_template must be specified", pData->iidx); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + /* a valid delivery mode must be defined : a 0 means that an invalid value + * has been done */ + if (!pData->delivery_mode) + { + LogError(0, RS_RET_CONF_PARAM_INVLD, "omrabbitmq module %d disabled: " + "parameter delivery_mode must be " + "TRANSIENT or PERSISTENT (default)", pData->iidx); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + /* first if a template for message body is set let verify its existence */ + if (pData->body_template && *pData->body_template && + tplFind(ourConf, (char*)pData->body_template, + strlen((char*)pData->body_template)) == NULL) + { + LogError(0, RS_RET_CONF_PARAM_INVLD, "omrabbitmq module %d : template '%s'" + " used for body does not exist !", + pData->iidx, pData->body_template); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + + /* Let's define the size of the doAction tab */ + CODE_STD_STRING_REQUESTnewActInst(1 + ((pData->routing_key_template) ? 1 : 0) + + ((pData->body_template && *pData->body_template == '\0') ? 0 : 1)); + + /* Set the plain text message props */ + memset(&pData->amqp_props_plaintext, 0, sizeof(amqp_basic_properties_t)); + pData->amqp_props_plaintext._flags = + AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_CONTENT_TYPE_FLAG; + pData->amqp_props_plaintext.delivery_mode = pData->delivery_mode; + /* persistent delivery mode */ + pData->amqp_props_plaintext.content_type = amqp_cstring_bytes("plain/text"); + if (pData->expiration.len) + { + pData->amqp_props_plaintext._flags |= AMQP_BASIC_EXPIRATION_FLAG; + pData->amqp_props_plaintext.expiration = pData->expiration; + } + + memcpy(&pData->amqp_props_tpl_type, &pData->amqp_props_plaintext, + sizeof(amqp_basic_properties_t)); + + /* The first position of doAction tab will contain the internal message */ + CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); + + // RabbitMQ properties initialization + if (pData->routing_key_template) + { + pData->idx_routing_key_template = 1; + CHKiRet(OMSRsetEntry(*ppOMSR, 1, + (uchar*)strdup((const char *)pData->routing_key_template), + OMSR_NO_RQD_TPL_OPTS)); + } + + /* if pData->body_template is NULL (not defined) then let's use former + * json format if pData->body_template is not an empty string then let's + * use it. In this case the content type is defined either + * by the template name or the user defined content_type if set + * otherwise raw data (unformatted) are sent this is done setting + * pData->idx_body_template to 0 */ + if (pData->body_template == NULL) + { /* no template */ + DBGPRINTF("Body_template is using default StdJSONFmt definition.\n"); + pData->idx_body_template = pData->idx_routing_key_template + 1; + CHKiRet(OMSRsetEntry(*ppOMSR, pData->idx_body_template, + (uchar*)strdup(" StdJSONFmt"), OMSR_NO_RQD_TPL_OPTS)); + pData->amqp_props_tpl_type.content_type = amqp_cstring_bytes("application/json"); + } + else if (*pData->body_template) + { + pData->idx_body_template = pData->idx_routing_key_template + 1; + CHKiRet(OMSRsetEntry(*ppOMSR, pData->idx_body_template, + (uchar*)strdup((const char *)pData->body_template), + OMSR_NO_RQD_TPL_OPTS)); + pData->amqp_props_tpl_type.content_type = amqp_cstring_bytes( + (pData->content_type) + ? pData->content_type + : (char*)pData->body_template); + }else{ + pData->idx_body_template = 0; + pData->amqp_props_tpl_type.content_type = amqp_cstring_bytes( + (pData->content_type) + ? pData->content_type + :"raw"); + } + + /* treatment of the server parameter + * first the default port */ + pData->server2.port = pData->server1.port = port ? port : 5672; + + char *temp; + int p; + pData->server1.host = host; + + /* Is there more than one server in parameter */ + if ((pData->server2.host = strchr(pData->server1.host,' ')) != NULL) + { + *pData->server2.host++ ='\0'; + /* is there a port with the second server */ + if ((temp = strchr(pData->server2.host,':')) != NULL) + { + *temp++ ='\0'; + p = atoi(temp); + if (p) pData->server2.port = p; + } + } + + /* is there a port with the first/unique server */ + if ((temp = strchr(pData->server1.host,':')) != NULL) + { + *temp++ ='\0'; + p = atoi(temp); + if (p) pData->server1.port = p; + } + + pData->vhost = vhost ? vhost : strdup("/"); + pData->user = user ? user : strdup(""); + pData->password = password ? password : strdup(""); + + init_recover(&pData->recover_policy, recover); + + if (recover) + free(recover); + + dbgPrintInstInfo(pData); + +CODE_STD_FINALIZERnewActInst + cnfparamvalsDestruct(pvals, &actpblk); +ENDnewActInst + + +NO_LEGACY_CONF_parseSelectorAct + + +BEGINmodExit +CODESTARTmodExit + objRelease(glbl, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance + memset(pWrkrData, 0, sizeof(wrkrInstanceData_t)); + + pWrkrData->pData = pData; + + pthread_mutex_init(&pWrkrData->send_mutex, NULL); + pthread_cond_init(&pWrkrData->cond, NULL); + + pWrkrData->state = RS_RET_SUSPENDED; + pWrkrData->iidx = pData->iidx; + pWrkrData->widx = ++pData->nbWrkr; + + memcpy(&(pWrkrData->recover_policy), &(pData->recover_policy), + sizeof(recover_t)); + + if (pData->server2.host && *pData->server2.host) { + time_t odd = time(NULL) % 2; + memcpy(&(pWrkrData->serverPrefered.s), (odd) ? + &pData->server1 : &pData->server2, sizeof(server_t)); + memcpy(&(pWrkrData->serverBackup.s), (odd) ? + &pData->server2 : &pData->server1, sizeof(server_t)); + }else{ + memcpy(&(pWrkrData->serverPrefered.s), &pData->server1, sizeof(server_t)); + } + pWrkrData->serverActive = &pWrkrData->serverPrefered; + + startAMQPConnection(pWrkrData); + +ENDcreateWrkrInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance + + if (pWrkrData != NULL) { + closeAMQPConnection(pWrkrData); + + pthread_mutex_destroy(&(pWrkrData->send_mutex)); + pthread_cond_destroy(&(pWrkrData->cond)); + } +ENDfreeWrkrInstance + +BEGINqueryEtryPt +CODESTARTqueryEtryPt + CODEqueryEtryPt_STD_OMOD_QUERIES + CODEqueryEtryPt_STD_OMOD8_QUERIES + CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); +ENDmodInit diff --git a/contrib/omtcl/Makefile.am b/contrib/omtcl/Makefile.am new file mode 100644 index 0000000..342f11b --- /dev/null +++ b/contrib/omtcl/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = omtcl.la + +omtcl_la_SOURCES = omtcl.c +omtcl_la_CPPFLAGS = $(RSRT_CFLAGS) $(TCL_INCLUDE_SPEC) +omtcl_la_LDFLAGS = -module +omtcl_la_LIBADD = $(TCL_LIB_SPEC) + +EXTRA_DIST = diff --git a/contrib/omtcl/Makefile.in b/contrib/omtcl/Makefile.in new file mode 100644 index 0000000..7937c37 --- /dev/null +++ b/contrib/omtcl/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/omtcl +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +am__DEPENDENCIES_1 = +omtcl_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_omtcl_la_OBJECTS = omtcl_la-omtcl.lo +omtcl_la_OBJECTS = $(am_omtcl_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +omtcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(omtcl_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/omtcl_la-omtcl.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(omtcl_la_SOURCES) +DIST_SOURCES = $(omtcl_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = omtcl.la +omtcl_la_SOURCES = omtcl.c +omtcl_la_CPPFLAGS = $(RSRT_CFLAGS) $(TCL_INCLUDE_SPEC) +omtcl_la_LDFLAGS = -module +omtcl_la_LIBADD = $(TCL_LIB_SPEC) +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omtcl/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/omtcl/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +omtcl.la: $(omtcl_la_OBJECTS) $(omtcl_la_DEPENDENCIES) $(EXTRA_omtcl_la_DEPENDENCIES) + $(AM_V_CCLD)$(omtcl_la_LINK) -rpath $(pkglibdir) $(omtcl_la_OBJECTS) $(omtcl_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omtcl_la-omtcl.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +omtcl_la-omtcl.lo: omtcl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtcl_la-omtcl.lo -MD -MP -MF $(DEPDIR)/omtcl_la-omtcl.Tpo -c -o omtcl_la-omtcl.lo `test -f 'omtcl.c' || echo '$(srcdir)/'`omtcl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omtcl_la-omtcl.Tpo $(DEPDIR)/omtcl_la-omtcl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omtcl.c' object='omtcl_la-omtcl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtcl_la-omtcl.lo `test -f 'omtcl.c' || echo '$(srcdir)/'`omtcl.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/omtcl_la-omtcl.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/omtcl_la-omtcl.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/omtcl/omtcl.c b/contrib/omtcl/omtcl.c new file mode 100644 index 0000000..c0f7f66 --- /dev/null +++ b/contrib/omtcl/omtcl.c @@ -0,0 +1,164 @@ +/* omtcl.c + * invoke a tcl procedure for every message + * + * NOTE: read comments in module-template.h for more specifics! + * + * File begun on 2016-05-16 by fcr + * + * Copyright 2016 Francisco Castro <fcr@adinet.com.uy> + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +/* work around gcc-7 build problems - acceptable for contributed module */ +#pragma GCC diagnostic ignored "-Wundef" + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include "conf.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "tcl.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP + +DEF_OMOD_STATIC_DATA + +typedef struct _instanceData { + Tcl_Interp * interp; + Tcl_Obj * cmdName; +} instanceData; + +typedef struct wrkrInstanceData { + instanceData * pData; +} wrkrInstanceData_t; + +BEGINinitConfVars +CODESTARTinitConfVars +ENDinitConfVars + +BEGINcreateInstance +CODESTARTcreateInstance + pData->interp = Tcl_CreateInterp(); + pData->cmdName = NULL; +ENDcreateInstance + +BEGINcreateWrkrInstance +CODESTARTcreateWrkrInstance +ENDcreateWrkrInstance + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +/* not compatible with message reduction */ +ENDisCompatibleWithFeature + +BEGINfreeInstance +CODESTARTfreeInstance + if(pData->cmdName != NULL) + Tcl_DecrRefCount(pData->cmdName); + Tcl_DeleteInterp(pData->interp); +ENDfreeInstance + +BEGINfreeWrkrInstance +CODESTARTfreeWrkrInstance +ENDfreeWrkrInstance + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +ENDdbgPrintInstInfo + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +BEGINdoAction + Tcl_Obj * objv[2]; +CODESTARTdoAction + objv[0] = pWrkrData->pData->cmdName; + objv[1] = Tcl_NewStringObj((char*) ppString[0], -1); + if (Tcl_EvalObjv(pWrkrData->pData->interp, 2, objv, 0) != TCL_OK) { + iRet = RS_RET_ERR; + DBGPRINTF("omtcl: %s", Tcl_GetStringResult(pWrkrData->pData->interp)); + } +ENDdoAction + +BEGINparseSelectorAct + char fileName[PATH_MAX+1]; + char buffer[4096]; +CODESTARTparseSelectorAct +CODE_STD_STRING_REQUESTparseSelectorAct(1) + if(strncmp((char*) p, ":omtcl:", sizeof(":omtcl:") - 1)) { + ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); + } + p += sizeof(":omtcl:") - 1; + + if(getSubString(&p, fileName, PATH_MAX+1, ',') || getSubString(&p, buffer, 4096, ';') || !strlen(buffer)) { + LogError(0, RS_RET_INVALID_PARAMS, "Invalid OmTcl parameters"); + ABORT_FINALIZE(RS_RET_INVALID_PARAMS); + } + + if (*(p-1) == ';') + --p; + + CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, (uchar*) "RSYSLOG_FileFormat")); + + CHKiRet(createInstance(&pData)); + pData->cmdName = Tcl_NewStringObj(buffer, -1); + Tcl_IncrRefCount(pData->cmdName); + + // TODO parse arguments: file,procname + if (Tcl_EvalFile(pData->interp, fileName) == TCL_ERROR) { + LogError(0, RS_RET_CONFIG_ERROR, "Loading Tcl script: %s", Tcl_GetStringResult(pData->interp)); + ABORT_FINALIZE(RS_RET_CONFIG_ERROR); + } + +CODE_STD_FINALIZERparseSelectorAct +ENDparseSelectorAct + +BEGINmodExit +CODESTARTmodExit +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_OMOD8_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit +INITLegCnfVars + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("omtcl: module compiled with rsyslog version %s.\n", VERSION); + +ENDmodInit + diff --git a/contrib/pmaixforwardedfrom/Makefile.am b/contrib/pmaixforwardedfrom/Makefile.am new file mode 100644 index 0000000..af359d3 --- /dev/null +++ b/contrib/pmaixforwardedfrom/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = pmaixforwardedfrom.la
+
+pmaixforwardedfrom_la_SOURCES = pmaixforwardedfrom.c
+pmaixforwardedfrom_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools
+pmaixforwardedfrom_la_LDFLAGS = -module -avoid-version
+pmaixforwardedfrom_la_LIBADD =
+
+EXTRA_DIST =
diff --git a/contrib/pmaixforwardedfrom/Makefile.in b/contrib/pmaixforwardedfrom/Makefile.in new file mode 100644 index 0000000..dab4de0 --- /dev/null +++ b/contrib/pmaixforwardedfrom/Makefile.in @@ -0,0 +1,800 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/pmaixforwardedfrom +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +pmaixforwardedfrom_la_DEPENDENCIES = +am_pmaixforwardedfrom_la_OBJECTS = \ + pmaixforwardedfrom_la-pmaixforwardedfrom.lo +pmaixforwardedfrom_la_OBJECTS = $(am_pmaixforwardedfrom_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pmaixforwardedfrom_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(pmaixforwardedfrom_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(pmaixforwardedfrom_la_SOURCES) +DIST_SOURCES = $(pmaixforwardedfrom_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = pmaixforwardedfrom.la +pmaixforwardedfrom_la_SOURCES = pmaixforwardedfrom.c +pmaixforwardedfrom_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmaixforwardedfrom_la_LDFLAGS = -module -avoid-version +pmaixforwardedfrom_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmaixforwardedfrom/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/pmaixforwardedfrom/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pmaixforwardedfrom.la: $(pmaixforwardedfrom_la_OBJECTS) $(pmaixforwardedfrom_la_DEPENDENCIES) $(EXTRA_pmaixforwardedfrom_la_DEPENDENCIES) + $(AM_V_CCLD)$(pmaixforwardedfrom_la_LINK) -rpath $(pkglibdir) $(pmaixforwardedfrom_la_OBJECTS) $(pmaixforwardedfrom_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +pmaixforwardedfrom_la-pmaixforwardedfrom.lo: pmaixforwardedfrom.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmaixforwardedfrom_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmaixforwardedfrom_la-pmaixforwardedfrom.lo -MD -MP -MF $(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Tpo -c -o pmaixforwardedfrom_la-pmaixforwardedfrom.lo `test -f 'pmaixforwardedfrom.c' || echo '$(srcdir)/'`pmaixforwardedfrom.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Tpo $(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmaixforwardedfrom.c' object='pmaixforwardedfrom_la-pmaixforwardedfrom.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmaixforwardedfrom_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmaixforwardedfrom_la-pmaixforwardedfrom.lo `test -f 'pmaixforwardedfrom.c' || echo '$(srcdir)/'`pmaixforwardedfrom.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c b/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c new file mode 100644 index 0000000..f27a236 --- /dev/null +++ b/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c @@ -0,0 +1,185 @@ +/* pmaixforwardedfrom.c + * + * this cleans up messages forwarded from AIX + * + * instead of actually parsing the message, this modifies the message and then falls through to allow a + * later parser to handle the now modified message + * + * created 2010-12-13 by David Lang based on pmlastmsg + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "msg.h" +#include "module-template.h" +#include "glbl.h" +#include "errmsg.h" +#include "parser.h" +#include "datetime.h" +#include "unicode-helper.h" +#include "rsconf.h" + +MODULE_TYPE_PARSER +MODULE_TYPE_NOKEEP +PARSER_NAME("rsyslog.aixforwardedfrom") + +/* internal structures + */ +DEF_PMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(parser) +DEFobjCurrIf(datetime) + + +/* static data */ +static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATUREAutomaticSanitazion) + iRet = RS_RET_OK; + if(eFeat == sFEATUREAutomaticPRIParsing) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +BEGINparse + uchar *p2parse; + int lenMsg; + int skipLen = 0; +#define OpeningText "Message forwarded from " +#define OpeningText2 "From " +CODESTARTparse + dbgprintf("Message will now be parsed by fix AIX Forwarded From parser.\n"); + assert(pMsg != NULL); + assert(pMsg->pszRawMsg != NULL); + lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; + /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ + + /* check if this message is of the type we handle in this (very limited) parser */ + /* first, we permit SP */ + while(lenMsg && *p2parse == ' ') { + --lenMsg; + ++p2parse; + } + if((unsigned) lenMsg < 24) { + /* too short, can not be "our" message */ + /* minimum message, 16 character timestamp, 'From ", 1 character name, ': '*/ + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + + /* skip over timestamp */ + lenMsg -=16; + p2parse +=16; + /* if there is the string "Message forwarded from " were the hostname should be */ + if(!strncasecmp((char*) p2parse, OpeningText, sizeof(OpeningText)-1)) + skipLen = 23; + /* or "From " */ + if(!strncasecmp((char*) p2parse, OpeningText2, sizeof(OpeningText2)-1)) + skipLen = 5; + DBGPRINTF("pmaixforwardedfrom: skipLen %d\n", skipLen); + if(!skipLen) { + /* wrong opening text */ + DBGPRINTF("not a AIX message forwarded from mangled log!\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + /* bump the message portion up by skipLen(23 or 5) characters to overwrite the "Message forwarded from +" or "From " with the hostname */ + lenMsg -=skipLen; + if(lenMsg < 2) { + dbgprintf("not a AIX message forwarded from message has nothing after header\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + memmove(p2parse, p2parse + skipLen, lenMsg); + *(p2parse + lenMsg) = '\n'; + *(p2parse + lenMsg + 1) = '\0'; + pMsg->iLenRawMsg -=skipLen; + pMsg->iLenMSG -=skipLen; + /* now look for the : after the hostname to walk past the hostname, also watch for a space in case this isn't +really an AIX log, but has a similar preamble */ + while(lenMsg && *p2parse != ' ' && *p2parse != ':') { + --lenMsg; + ++p2parse; + } + if (lenMsg < 1) { + dbgprintf("not a AIX message forwarded from message has nothing after colon " + "or no colon at all\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + if (lenMsg && *p2parse != ':') { + DBGPRINTF("not a AIX message forwarded from mangled log but similar enough that the preamble has " + "been removed\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + /* bump the message portion up by one character to overwrite the extra : */ + lenMsg -=1; + memmove(p2parse, p2parse + 1, lenMsg); + *(p2parse + lenMsg) = '\n'; + *(p2parse + lenMsg + 1) = '\0'; + pMsg->iLenRawMsg -=1; + pMsg->iLenMSG -=1; + /* now, claim to abort so that something else can parse the now modified message */ + DBGPRINTF("pmaixforwardedfrom: new message: [%d]'%s'\n", lenMsg, pMsg->pszRawMsg + pMsg->offAfterPRI); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + +finalize_it: +ENDparse + + +BEGINmodExit +CODESTARTmodExit + /* release what we no longer need */ + objRelease(glbl, CORE_COMPONENT); + objRelease(parser, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_PMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(parser, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + + DBGPRINTF("aixforwardedfrom parser init called, compiled with version %s\n", VERSION); + bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); + /* cache value, is set only during rsyslogd option processing */ + + +ENDmodInit + +/* vim:set ai: + */ diff --git a/contrib/pmcisconames/Makefile.am b/contrib/pmcisconames/Makefile.am new file mode 100644 index 0000000..16ed347 --- /dev/null +++ b/contrib/pmcisconames/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = pmcisconames.la + +pmcisconames_la_SOURCES = pmcisconames.c +pmcisconames_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmcisconames_la_LDFLAGS = -module -avoid-version +pmcisconames_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/pmcisconames/Makefile.in b/contrib/pmcisconames/Makefile.in new file mode 100644 index 0000000..b45fa4b --- /dev/null +++ b/contrib/pmcisconames/Makefile.in @@ -0,0 +1,798 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/pmcisconames +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +pmcisconames_la_DEPENDENCIES = +am_pmcisconames_la_OBJECTS = pmcisconames_la-pmcisconames.lo +pmcisconames_la_OBJECTS = $(am_pmcisconames_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pmcisconames_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(pmcisconames_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(pmcisconames_la_SOURCES) +DIST_SOURCES = $(pmcisconames_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = pmcisconames.la +pmcisconames_la_SOURCES = pmcisconames.c +pmcisconames_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmcisconames_la_LDFLAGS = -module -avoid-version +pmcisconames_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmcisconames/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/pmcisconames/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pmcisconames.la: $(pmcisconames_la_OBJECTS) $(pmcisconames_la_DEPENDENCIES) $(EXTRA_pmcisconames_la_DEPENDENCIES) + $(AM_V_CCLD)$(pmcisconames_la_LINK) -rpath $(pkglibdir) $(pmcisconames_la_OBJECTS) $(pmcisconames_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +pmcisconames_la-pmcisconames.lo: pmcisconames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmcisconames_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmcisconames_la-pmcisconames.lo -MD -MP -MF $(DEPDIR)/pmcisconames_la-pmcisconames.Tpo -c -o pmcisconames_la-pmcisconames.lo `test -f 'pmcisconames.c' || echo '$(srcdir)/'`pmcisconames.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmcisconames_la-pmcisconames.Tpo $(DEPDIR)/pmcisconames_la-pmcisconames.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmcisconames.c' object='pmcisconames_la-pmcisconames.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmcisconames_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmcisconames_la-pmcisconames.lo `test -f 'pmcisconames.c' || echo '$(srcdir)/'`pmcisconames.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/pmcisconames/pmcisconames.c b/contrib/pmcisconames/pmcisconames.c new file mode 100644 index 0000000..0d7cb51 --- /dev/null +++ b/contrib/pmcisconames/pmcisconames.c @@ -0,0 +1,185 @@ +/* pmcisconames.c + * + * this detects logs sent by Cisco devices that mangle their syslog output when you tell them to log by name + * by adding ' :' between the name and the %XXX-X-XXXXXXX: tag + * + * instead of actually parsing the message, this modifies the message and then falls through to allow a later + * parser to handle the now modified message + * + * created 2010-12-13 by David Lang based on pmlastmsg + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "msg.h" +#include "module-template.h" +#include "glbl.h" +#include "errmsg.h" +#include "parser.h" +#include "datetime.h" +#include "unicode-helper.h" +#include "rsconf.h" + +MODULE_TYPE_PARSER +MODULE_TYPE_NOKEEP +PARSER_NAME("rsyslog.cisconames") + +/* internal structures + */ +DEF_PMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(parser) +DEFobjCurrIf(datetime) + + +/* static data */ +static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATUREAutomaticSanitazion) + iRet = RS_RET_OK; + if(eFeat == sFEATUREAutomaticPRIParsing) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +BEGINparse + uchar *p2parse; + int lenMsg; +#define OpeningText ": %" +CODESTARTparse + dbgprintf("Message will now be parsed by fix Cisco Names parser.\n"); + assert(pMsg != NULL); + assert(pMsg->pszRawMsg != NULL); + lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; + /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ + + /* check if this message is of the type we handle in this (very limited) parser */ + /* first, we permit SP */ + while(lenMsg && *p2parse == ' ') { + --lenMsg; + ++p2parse; + } + if((unsigned) lenMsg < 34) { + /* too short, can not be "our" message */ + /* minimum message, 16 character timestamp, 1 character name, ' : %ASA-1-000000: '*/ + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + /* check if the timestamp is a 16 character or 21 character timestamp + 'Mmm DD HH:MM:SS ' spaces at 3,6,15 : at 9,12 + 'Mmm DD YYYY HH:MM:SS ' spaces at 3,6,11,20 : at 14,17 + check for the : first as that will differentiate the two conditions the fastest + this allows the compiler to short circuit the rst of the tests if it is the wrong timestamp + but still check the rest to see if it looks correct + */ + if ( *(p2parse + 9) == ':' && *(p2parse + 12) == ':' && *(p2parse + 3) == ' ' && *(p2parse + 6) == ' ' + && *(p2parse + 15) == ' ') { + /* skip over timestamp */ + dbgprintf("short timestamp found\n"); + lenMsg -=16; + p2parse +=16; + } else { + if ( *(p2parse + 14) == ':' && *(p2parse + 17) == ':' && *(p2parse + 3) == ' ' + && *(p2parse + 6) == ' ' && *(p2parse + 11) == ' ' && *(p2parse + 20) == ' ') { + /* skip over timestamp */ + dbgprintf("long timestamp found\n"); + lenMsg -=21; + p2parse +=21; + } else { + dbgprintf("timestamp is not one of the valid formats\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + } + /* now look for the next space to walk past the hostname */ + while(lenMsg && *p2parse != ' ') { + --lenMsg; + ++p2parse; + } + /* Note: we deliberately count the 0-byte below because we need to go chars+1! */ + if(lenMsg < (int) sizeof(OpeningText)) { + dbgprintf("pmcisconames: too short for being cisco messages\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + /* skip the space after the hostname */ + lenMsg -=1; + p2parse +=1; + /* if the syslog tag is : and the next thing starts with a % assume that this is a mangled cisco + log and fix it */ + if(strncasecmp((char*) p2parse, OpeningText, sizeof(OpeningText)-1) != 0) { + /* wrong opening text */ + DBGPRINTF("not a cisco name mangled log!\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + /* bump the message portion up by two characters to overwrite the extra : */ + lenMsg -=2; + memmove(p2parse, p2parse + 2, lenMsg); + *(p2parse + lenMsg) = '\n'; + *(p2parse + lenMsg + 1) = '\0'; + pMsg->iLenRawMsg -=2; + pMsg->iLenMSG -=2; + /* now, claim to abort so that something else can parse the now modified message */ + DBGPRINTF("pmcisconames: new message: [%d]'%s'\n", lenMsg, p2parse); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + +finalize_it: +ENDparse + + +BEGINmodExit +CODESTARTmodExit + /* release what we no longer need */ + objRelease(glbl, CORE_COMPONENT); + objRelease(parser, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_PMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(parser, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + + DBGPRINTF("cisconames parser init called, compiled with version %s\n", VERSION); + bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); + /* cache value, is set only during rsyslogd option processing */ + + +ENDmodInit + +/* vim:set ai: + */ diff --git a/contrib/pmdb2diag/Makefile.am b/contrib/pmdb2diag/Makefile.am new file mode 100644 index 0000000..5bde231 --- /dev/null +++ b/contrib/pmdb2diag/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = pmdb2diag.la + +pmdb2diag_la_SOURCES = pmdb2diag.c +pmdb2diag_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmdb2diag_la_LDFLAGS = -module -avoid-version +pmdb2diag_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/pmdb2diag/Makefile.in b/contrib/pmdb2diag/Makefile.in new file mode 100644 index 0000000..4587599 --- /dev/null +++ b/contrib/pmdb2diag/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/pmdb2diag +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +pmdb2diag_la_DEPENDENCIES = +am_pmdb2diag_la_OBJECTS = pmdb2diag_la-pmdb2diag.lo +pmdb2diag_la_OBJECTS = $(am_pmdb2diag_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pmdb2diag_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(pmdb2diag_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(pmdb2diag_la_SOURCES) +DIST_SOURCES = $(pmdb2diag_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = pmdb2diag.la +pmdb2diag_la_SOURCES = pmdb2diag.c +pmdb2diag_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmdb2diag_la_LDFLAGS = -module -avoid-version +pmdb2diag_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmdb2diag/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/pmdb2diag/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pmdb2diag.la: $(pmdb2diag_la_OBJECTS) $(pmdb2diag_la_DEPENDENCIES) $(EXTRA_pmdb2diag_la_DEPENDENCIES) + $(AM_V_CCLD)$(pmdb2diag_la_LINK) -rpath $(pkglibdir) $(pmdb2diag_la_OBJECTS) $(pmdb2diag_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +pmdb2diag_la-pmdb2diag.lo: pmdb2diag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmdb2diag_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmdb2diag_la-pmdb2diag.lo -MD -MP -MF $(DEPDIR)/pmdb2diag_la-pmdb2diag.Tpo -c -o pmdb2diag_la-pmdb2diag.lo `test -f 'pmdb2diag.c' || echo '$(srcdir)/'`pmdb2diag.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmdb2diag_la-pmdb2diag.Tpo $(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmdb2diag.c' object='pmdb2diag_la-pmdb2diag.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmdb2diag_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmdb2diag_la-pmdb2diag.lo `test -f 'pmdb2diag.c' || echo '$(srcdir)/'`pmdb2diag.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/pmdb2diag/pmdb2diag.c b/contrib/pmdb2diag/pmdb2diag.c new file mode 100644 index 0000000..5810eb4 --- /dev/null +++ b/contrib/pmdb2diag/pmdb2diag.c @@ -0,0 +1,305 @@ +/* pmdb2diag.c + * + * This is a parser module specifically for DB2diag log file. + * It extracted program, pid and severity from the log. + * + * Copyright 2015 Philippe Duveau @ Pari Mutuel Urbain. + * + * This file is contribution of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#include "rsyslog.h" +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "msg.h" +#include "module-template.h" +#include "glbl.h" +#include "errmsg.h" +#include "parser.h" +#include "datetime.h" +#include "unicode-helper.h" + +MODULE_TYPE_PARSER +MODULE_TYPE_NOKEEP +PARSER_NAME("db2.diag") +MODULE_CNFNAME("pmdb2diag") + +/* internal structures + */ +DEF_PMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(datetime) + +/* input instance parameters */ +static struct cnfparamdescr parserpdescr[] = { + { "levelpos", eCmdHdlrInt, 0 }, + { "timepos", eCmdHdlrInt, 0 }, + { "timeformat", eCmdHdlrString, 0 }, + { "pidstarttoprogstartshift", eCmdHdlrInt, 0 }, +}; +static struct cnfparamblk parserpblk = + { CNFPARAMBLK_VERSION, + sizeof(parserpdescr)/sizeof(struct cnfparamdescr), + parserpdescr + }; + +struct instanceConf_s { + int levelpos; /* expected severity position in read message */ + int timepos; /* expected time position in read message */ + int pidstarttoprogstartshift; /* position of prog related to pid */ + char *timeformat; /* format of timestamp in read message */ + char sepSec; /* decimal separator between second and milliseconds */ +}; + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATUREAutomaticPRIParsing) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +BEGINparse2 + struct tm tm; + char *ms, *timepos, *pid, *prog, *eprog, *backslash, *end, *lvl; + int lprog, lpid, lvl_len; + char buffer[128]; +CODESTARTparse2 + assert(pMsg != NULL); + assert(pMsg->pszRawMsg != NULL); + + DBGPRINTF("Message will now be parsed by \"db2diag\" parser.\n"); + if(pMsg->iLenRawMsg - (int)pMsg->offAfterPRI < pInst->levelpos+4) + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + + /* Instead of comparing strings which a waste of cpu cycles we take interpret the 4 first chars of + * level read it as int32 and compare it to same interpretation of our constant "levels" + * So this test is not sensitive to ENDIANESS. This is not a clean way but very efficient. + */ + lvl = (char*)(pMsg->pszRawMsg + pMsg->offAfterPRI + pInst->levelpos); + + switch (*lvl) { + case 'C': /* Critical */ + pMsg->iSeverity = LOG_EMERG; + lvl_len = 8; + break; + case 'A': /* Alert */ + pMsg->iSeverity = LOG_ALERT; + lvl_len = 5; + break; + case 'S': /* Severe */ + pMsg->iSeverity = LOG_CRIT; + lvl_len = 6; + break; + case 'E': /* Error / Event */ + pMsg->iSeverity = (lvl[1] == 'r') ? LOG_ERR : LOG_NOTICE; + lvl_len = 5; + break; + case 'W': /* Warning */ + pMsg->iSeverity = LOG_WARNING; + lvl_len = 7; + break; + case 'I': /* Info */ + pMsg->iSeverity = LOG_INFO; + lvl_len = 4; + break; + case 'D': /* Debug */ + pMsg->iSeverity = LOG_DEBUG; + lvl_len = 5; + break; + default: + /* perhaps the message does not contain a proper level if so don't parse the log */ + ABORT_FINALIZE(0); + } + + /* let recheck with the real level len */ + if(pMsg->iLenRawMsg - (int)pMsg->offAfterPRI < pInst->levelpos+lvl_len) + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + + DBGPRINTF("db2parse Level %d\n", pMsg->iSeverity); + + end = (char*)pMsg->pszRawMsg + pMsg->iLenRawMsg ; + + timepos = (char*)pMsg->pszRawMsg + pMsg->offAfterPRI + pInst->timepos; + + DBGPRINTF("db2parse Time %.30s\n", timepos); + ms = strptime(timepos, pInst->timeformat, &tm); + + if (ms > timepos && *(ms-1) == pInst->sepSec) + { + /* the timestamp could be properly interpreted by strptime & our format then set proper timestamp */ + int secfrac = 0, tzoff = 0; + + char *tzpos = strchr(ms, '+'); + if (!tzpos) tzpos = strchr(ms, '-'); + if (!tzpos) tzpos = (char*)"+"; + + sscanf(ms, (*tzpos == '+') ? "%d+%d " : "%d-%d ", &secfrac, &tzoff); + + pMsg->tTIMESTAMP.year = tm.tm_year+1900; + pMsg->tTIMESTAMP.month = tm.tm_mon + 1; + pMsg->tTIMESTAMP.day = tm.tm_mday; + pMsg->tTIMESTAMP.hour = tm.tm_hour; + pMsg->tTIMESTAMP.minute = tm.tm_min; + pMsg->tTIMESTAMP.second = tm.tm_sec; + pMsg->tTIMESTAMP.secfrac = secfrac; + pMsg->tTIMESTAMP.secfracPrecision = tzpos-ms; + pMsg->tTIMESTAMP.OffsetMode = *tzpos; + pMsg->tTIMESTAMP.OffsetHour = tzoff / 60; + pMsg->tTIMESTAMP.OffsetMinute = tzoff % 60; + } + + pid = strchr((char*)pMsg->pszRawMsg + pInst->levelpos + lvl_len, ':'); + if (!pid || pid>=end) ABORT_FINALIZE(0); + pid += 2; + lpid = strchr(pid, ' ') - pid; + + DBGPRINTF("db2parse pid %.*s\n", lpid, pid); + + /* set the pid */ + snprintf(buffer, 128, "%.*s", lpid, pid); + MsgSetPROCID(pMsg, buffer); + + prog = pid + pInst->pidstarttoprogstartshift; /* this offset between start of pid to start of prog */ + if (prog>=end) ABORT_FINALIZE(0); + + eprog = strchr(prog, ' '); /* let find the end of the program */ + if (eprog && eprog>=end) ABORT_FINALIZE(0); + + backslash = strchr(prog, '\\'); /* perhaps program contain an backslash */ + if (!backslash || backslash>=end) backslash = end; + + /* Determine the final length of prog */ + lprog = (eprog && eprog<backslash) ? eprog-prog : backslash-prog; + + DBGPRINTF("db2parse prog %.*s lprog %d\n", lprog, prog, lprog); + +/* set the appname */ + snprintf(buffer, 128, "%.*s", lprog, prog); + MsgSetAPPNAME(pMsg, buffer); + + /* the original raw msg if not altered by the parser */ +finalize_it: +ENDparse2 + + +BEGINfreeParserInst +CODESTARTfreeParserInst + free(pInst->timeformat); +ENDfreeParserInst + +static rsRetVal +createInstance(instanceConf_t **ppInst) +{ + instanceConf_t *pInst; + DEFiRet; + CHKmalloc(pInst = (instanceConf_t *)malloc(sizeof(instanceConf_t))); + pInst->timeformat = NULL; + pInst->levelpos = 59; + pInst->timepos = 0; + pInst->pidstarttoprogstartshift = 49; + + *ppInst = pInst; +finalize_it: + RETiRet; +} + +BEGINnewParserInst + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTnewParserInst + inst = NULL; + + DBGPRINTF("newParserInst (pmdb2diag)\n"); + CHKiRet(createInstance(&inst)); + + if (lst) + { + if((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + DBGPRINTF("parser param blk in pmdb2diag:\n"); + cnfparamsPrint(&parserpblk, pvals); + } + + for(i = 0 ; i < parserpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(parserpblk.descr[i].name, "timeformat")) { + inst->timeformat = (char*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(parserpblk.descr[i].name, "timepos")) { + inst->timepos = (int)pvals[i].val.d.n; + } else if(!strcmp(parserpblk.descr[i].name, "levelpos")) { + inst->levelpos = (int) pvals[i].val.d.n; + } else if(!strcmp(parserpblk.descr[i].name, "pidstarttoprogstartshift")) { + inst->pidstarttoprogstartshift = (int) pvals[i].val.d.n; + } else { + DBGPRINTF("pmdb2diag: program error, non-handled " + "param '%s'\n", parserpblk.descr[i].name); + } + } + } + + if (inst->timeformat == NULL) + { + inst->timeformat = strdup("%Y-%m-%d-%H.%M.%S."); + inst->sepSec = '.'; + }else + inst->sepSec = inst->timeformat[strlen(inst->timeformat)-1]; + + DBGPRINTF("pmdb2diag: parsing date/time with '%s' at position %d and level at position %d.\n", + inst->timeformat, inst->timepos, inst->levelpos); + +finalize_it: +CODE_STD_FINALIZERnewParserInst + if(lst != NULL) + cnfparamvalsDestruct(pvals, &parserpblk); +ENDnewParserInst + +BEGINmodExit +CODESTARTmodExit + /* release what we no longer need */ + objRelease(glbl, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_PMOD2_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + DBGPRINTF("pmdb2diag parser init called, compiled with version %s\n", VERSION); +ENDmodInit diff --git a/contrib/pmpanngfw/Makefile.am b/contrib/pmpanngfw/Makefile.am new file mode 100644 index 0000000..50d7556 --- /dev/null +++ b/contrib/pmpanngfw/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = pmpanngfw.la + +pmpanngfw_la_SOURCES = pmpanngfw.c +pmpanngfw_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmpanngfw_la_LDFLAGS = -module -avoid-version +pmpanngfw_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/pmpanngfw/Makefile.in b/contrib/pmpanngfw/Makefile.in new file mode 100644 index 0000000..d33221a --- /dev/null +++ b/contrib/pmpanngfw/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/pmpanngfw +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +pmpanngfw_la_DEPENDENCIES = +am_pmpanngfw_la_OBJECTS = pmpanngfw_la-pmpanngfw.lo +pmpanngfw_la_OBJECTS = $(am_pmpanngfw_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pmpanngfw_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(pmpanngfw_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(pmpanngfw_la_SOURCES) +DIST_SOURCES = $(pmpanngfw_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = pmpanngfw.la +pmpanngfw_la_SOURCES = pmpanngfw.c +pmpanngfw_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmpanngfw_la_LDFLAGS = -module -avoid-version +pmpanngfw_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmpanngfw/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/pmpanngfw/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pmpanngfw.la: $(pmpanngfw_la_OBJECTS) $(pmpanngfw_la_DEPENDENCIES) $(EXTRA_pmpanngfw_la_DEPENDENCIES) + $(AM_V_CCLD)$(pmpanngfw_la_LINK) -rpath $(pkglibdir) $(pmpanngfw_la_OBJECTS) $(pmpanngfw_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +pmpanngfw_la-pmpanngfw.lo: pmpanngfw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmpanngfw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmpanngfw_la-pmpanngfw.lo -MD -MP -MF $(DEPDIR)/pmpanngfw_la-pmpanngfw.Tpo -c -o pmpanngfw_la-pmpanngfw.lo `test -f 'pmpanngfw.c' || echo '$(srcdir)/'`pmpanngfw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmpanngfw_la-pmpanngfw.Tpo $(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmpanngfw.c' object='pmpanngfw_la-pmpanngfw.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmpanngfw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmpanngfw_la-pmpanngfw.lo `test -f 'pmpanngfw.c' || echo '$(srcdir)/'`pmpanngfw.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/pmpanngfw/pmpanngfw.c b/contrib/pmpanngfw/pmpanngfw.c new file mode 100644 index 0000000..c65cee7 --- /dev/null +++ b/contrib/pmpanngfw/pmpanngfw.c @@ -0,0 +1,296 @@ +/* pmpanngfw.c + * + * this detects logs sent by Palo Alto Networks NGFW and transforms CSV into tab-separated fields + * for handling inside the mmnormalize + * + * Example: foo,"bar,""baz""",qux becomes foo<TAB>bar,"baz"<TAB>qux + * + * created 2010-12-13 by Luigi Mori (lmori@paloaltonetworks.com) based on pmsnare + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "msg.h" +#include "module-template.h" +#include "glbl.h" +#include "errmsg.h" +#include "parser.h" +#include "datetime.h" +#include "unicode-helper.h" +#include "typedefs.h" +#include "rsconf.h" + +MODULE_TYPE_PARSER +MODULE_TYPE_NOKEEP +PARSER_NAME("rsyslog.panngfw") + +/* internal structures + */ +DEF_PMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(parser) +DEFobjCurrIf(datetime) + + +/* static data */ +static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ + +typedef struct { + uint64 value; + uint64 mask; +} log_type_t; + +const log_type_t log_types[] = { + { 0x002c544145524854ULL, 0x00FFFFFFFFFFFFFFULL }, /* THREAT, */ + { 0x2c43494646415254ULL, 0xFFFFFFFFFFFFFFFFULL }, /* TRAFFIC, */ + { 0x002c4d4554535953ULL, 0x00FFFFFFFFFFFFFFULL }, /* CONFIG */ + { 0x002c4749464e4f43ULL, 0x00FFFFFFFFFFFFFFULL } /* SYSTEM */ +}; + +#define NUM_LOG_TYPES (sizeof(log_types)/sizeof(log_type_t)) + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATUREAutomaticSanitazion) + iRet = RS_RET_OK; + if(eFeat == sFEATUREAutomaticPRIParsing) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + + +BEGINparse + uchar *p2parse; + uchar *p2target; + uchar *msgend; + int lenMsg, lenDelta; + int state; + int num_fields = 4; + uchar *f3_commas[3]; + int cur_comma = 0; + uint64 log_type; + unsigned int j; +CODESTARTparse + #define CSV_DELIMITER '\t' + #define STATE_FIELD_START 0 + #define STATE_IN_FIELD 1 + #define STATE_IN_QUOTE 2 + #define STATE_IN_QUOTE_QUOTE 3 + + state = STATE_FIELD_START; + + dbgprintf("Message will now be parsed by fix Palo Alto Networks NGFW parser.\n"); + assert(pMsg != NULL); + assert(pMsg->pszRawMsg != NULL); + + lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; + /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ + msgend = p2parse+lenMsg; + + dbgprintf("pmpanngfw: msg to look at: [%d]'%s'\n", lenMsg, p2parse); + + /* pass the first 3 fields */ + while(p2parse < msgend) { + if (*p2parse == ',') { + f3_commas[cur_comma] = p2parse; + if (cur_comma == 2) { + break; + } + cur_comma++; + } + p2parse++; + } + + /* check number of fields detected so far */ + if (cur_comma != 2) { + dbgprintf("not a PAN-OS syslog message: first 3 fields not found\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + + /* check msg length */ + p2parse++; + if ((p2parse > msgend) || ((msgend - p2parse) < (int)sizeof(uint64))) { + dbgprintf("not a PAN-OS syslog message: too short\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + + /* check log type */ + log_type = *((uint64 *)p2parse); + for(j = 0; j < (int)NUM_LOG_TYPES; j++) { + if ((log_type & log_types[j].mask) == log_types[j].value) + break; + } + if (j == NUM_LOG_TYPES) { + dbgprintf("not a PAN-OS syslog message, log type: %llx\n", log_type); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + + /* set the delimiter */ + *f3_commas[0] = CSV_DELIMITER; + *f3_commas[1] = CSV_DELIMITER; + *f3_commas[2] = CSV_DELIMITER; + + p2target = p2parse; + + while(p2parse < msgend) { + switch(state) { + case STATE_FIELD_START: + switch(*p2parse) { + case '"': + state = STATE_IN_QUOTE; + p2parse++; + break; + + case ',': + state = STATE_FIELD_START; + *p2target = CSV_DELIMITER; + num_fields++; + p2parse++; + p2target++; + break; + + default: + state = STATE_IN_FIELD; + *p2target = *p2parse; + p2parse++; + p2target++; + } + break; + + case STATE_IN_FIELD: + switch(*p2parse) { + case ',': + state = STATE_FIELD_START; + *p2target = CSV_DELIMITER; + num_fields++; + p2parse++; + p2target++; + break; + + default: + *p2target = *p2parse; + p2parse++; + p2target++; + } + break; + + case STATE_IN_QUOTE: + switch(*p2parse) { + case '"': + state = STATE_IN_QUOTE_QUOTE; + p2parse++; + break; + + default: + *p2target = *p2parse; + p2parse++; + p2target++; + } + break; + + case STATE_IN_QUOTE_QUOTE: + switch(*p2parse) { + case '"': + state = STATE_IN_QUOTE; + *p2target = *p2parse; + p2parse++; + p2target++; + break; + + case ',': + state = STATE_FIELD_START; + *p2target = CSV_DELIMITER; + num_fields++; + p2parse++; + p2target++; + break; + + default: + dbgprintf("pmpanngfw: martian char (%d) after quote in quote\n", *p2parse); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + break; + + default: + dbgprintf("how could I have reached this state ?!?\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + } + + if(p2parse != p2target) { + lenDelta = p2parse - p2target; + + assert(lenDelta >= 2); + + *p2target = 0; + + pMsg->iLenRawMsg -= lenDelta; + pMsg->iLenMSG -= lenDelta; + } + + lenMsg = p2target - (pMsg->pszRawMsg + pMsg->offAfterPRI); + + DBGPRINTF("pmpanngfw: new message: [%d]'%s'\n", lenMsg, pMsg->pszRawMsg + pMsg->offAfterPRI); + DBGPRINTF("pmpanngfw: # fields: %d\n", num_fields); + + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + +finalize_it: +ENDparse + + +BEGINmodExit +CODESTARTmodExit + /* release what we no longer need */ + objRelease(glbl, CORE_COMPONENT); + objRelease(parser, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_PMOD_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(parser, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + + DBGPRINTF("panngfw parser init called, compiled with version %s\n", VERSION); + bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); + /* cache value, is set only during rsyslogd option processing */ + + +ENDmodInit + +/* vim:set ai: + */ diff --git a/contrib/pmsnare/Makefile.am b/contrib/pmsnare/Makefile.am new file mode 100644 index 0000000..5b2696a --- /dev/null +++ b/contrib/pmsnare/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = pmsnare.la + +pmsnare_la_SOURCES = pmsnare.c +pmsnare_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmsnare_la_LDFLAGS = -module -avoid-version +pmsnare_la_LIBADD = + +EXTRA_DIST = diff --git a/contrib/pmsnare/Makefile.in b/contrib/pmsnare/Makefile.in new file mode 100644 index 0000000..9e94793 --- /dev/null +++ b/contrib/pmsnare/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = contrib/pmsnare +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ + $(top_srcdir)/m4/atomic_operations.m4 \ + $(top_srcdir)/m4/atomic_operations_64bit.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkglibdir)" +LTLIBRARIES = $(pkglib_LTLIBRARIES) +pmsnare_la_DEPENDENCIES = +am_pmsnare_la_OBJECTS = pmsnare_la-pmsnare.lo +pmsnare_la_OBJECTS = $(am_pmsnare_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +pmsnare_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(pmsnare_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/pmsnare_la-pmsnare.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(pmsnare_la_SOURCES) +DIST_SOURCES = $(pmsnare_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +APU_CFLAGS = @APU_CFLAGS@ +APU_LIBS = @APU_LIBS@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CIVETWEB_LIBS = @CIVETWEB_LIBS@ +CONF_FILE_PATH = @CONF_FILE_PATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL_CFLAGS = @CURL_CFLAGS@ +CURL_LIBS = @CURL_LIBS@ +CYGPATH_W = @CYGPATH_W@ +CZMQ_CFLAGS = @CZMQ_CFLAGS@ +CZMQ_LIBS = @CZMQ_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FAUP_LIBS = @FAUP_LIBS@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ +GNUTLS_LIBS = @GNUTLS_LIBS@ +GREP = @GREP@ +GSS_LIBS = @GSS_LIBS@ +GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ +GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ +HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ +HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ +HIREDIS_LIBS = @HIREDIS_LIBS@ +IMUDP_LIBS = @IMUDP_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +IP = @IP@ +JAVA = @JAVA@ +JAVAC = @JAVAC@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ +LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ +LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ +LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ +LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ +LIBDBI_LIBS = @LIBDBI_LIBS@ +LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ +LIBESTR_LIBS = @LIBESTR_LIBS@ +LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ +LIBEVENT_LIBS = @LIBEVENT_LIBS@ +LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ +LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ +LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ +LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ +LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ +LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ +LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ +LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ +LIBLZ4_LIBS = @LIBLZ4_LIBS@ +LIBM = @LIBM@ +LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ +LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ +LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ +LIBS = @LIBS@ +LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ +LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ +LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ +LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_CONFIG = @MYSQL_CONFIG@ +MYSQL_LIBS = @MYSQL_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_CFLAGS = @PGSQL_CFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PID_FILE_PATH = @PID_FILE_PATH@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTON_CFLAGS = @PROTON_CFLAGS@ +PROTON_LIBS = @PROTON_LIBS@ +PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ +PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ +RABBITMQ_LIBS = @RABBITMQ_LIBS@ +RANLIB = @RANLIB@ +READLINK = @READLINK@ +REDIS = @REDIS@ +RELP_CFLAGS = @RELP_CFLAGS@ +RELP_LIBS = @RELP_LIBS@ +RSRT_CFLAGS = @RSRT_CFLAGS@ +RSRT_CFLAGS1 = @RSRT_CFLAGS1@ +RSRT_LIBS = @RSRT_LIBS@ +RSRT_LIBS1 = @RSRT_LIBS1@ +RST2MAN = @RST2MAN@ +RT_LIBS = @RT_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SNMP_CFLAGS = @SNMP_CFLAGS@ +SNMP_LIBS = @SNMP_LIBS@ +SOL_LIBS = @SOL_LIBS@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ +UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +WARN_LDFLAGS = @WARN_LDFLAGS@ +WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ +WGET = @WGET@ +YACC = @YACC@ +YACC_FOUND = @YACC_FOUND@ +YFLAGS = @YFLAGS@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +ZSTD_CFLAGS = @ZSTD_CFLAGS@ +ZSTD_LIBS = @ZSTD_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moddirs = @moddirs@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +pkglib_LTLIBRARIES = pmsnare.la +pmsnare_la_SOURCES = pmsnare.c +pmsnare_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools +pmsnare_la_LDFLAGS = -module -avoid-version +pmsnare_la_LIBADD = +EXTRA_DIST = +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmsnare/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu contrib/pmsnare/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ + } + +uninstall-pkglibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +clean-pkglibLTLIBRARIES: + -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +pmsnare.la: $(pmsnare_la_OBJECTS) $(pmsnare_la_DEPENDENCIES) $(EXTRA_pmsnare_la_DEPENDENCIES) + $(AM_V_CCLD)$(pmsnare_la_LINK) -rpath $(pkglibdir) $(pmsnare_la_OBJECTS) $(pmsnare_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmsnare_la-pmsnare.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +pmsnare_la-pmsnare.lo: pmsnare.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmsnare_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmsnare_la-pmsnare.lo -MD -MP -MF $(DEPDIR)/pmsnare_la-pmsnare.Tpo -c -o pmsnare_la-pmsnare.lo `test -f 'pmsnare.c' || echo '$(srcdir)/'`pmsnare.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmsnare_la-pmsnare.Tpo $(DEPDIR)/pmsnare_la-pmsnare.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmsnare.c' object='pmsnare_la-pmsnare.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmsnare_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmsnare_la-pmsnare.lo `test -f 'pmsnare.c' || echo '$(srcdir)/'`pmsnare.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/pmsnare_la-pmsnare.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/pmsnare_la-pmsnare.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pkglibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/pmsnare/pmsnare.c b/contrib/pmsnare/pmsnare.c new file mode 100644 index 0000000..22f17f2 --- /dev/null +++ b/contrib/pmsnare/pmsnare.c @@ -0,0 +1,444 @@ +/* pmsnare.c + * + * this detects logs sent by Snare and cleans them up so that they can be processed by the normal parser + * + * there are two variations of this, if the client is set to 'syslog' mode it sends + * + * <pri>timestamp<sp>hostname<sp>tag<tab>otherstuff + * + * if the client is not set to syslog it sends + * + * hostname<tab>tag<tab>otherstuff + * + * The tabs can be represented in different ways. This module will auto-detect the tab representation based on + * the global config settings, but they can be overridden for each instance in the config file if needed. + * + * ToDo, take advantage of items in the message itself to set more friendly information + * where the normal parser will find it by re-writing more of the message + * + * Interesting information includes: + * + * in the case of windows snare messages: + * the system hostname is field 12 + * the severity is field 3 (criticality ranging form 0 to 4) + * the source of the log is field 4 and may be able to be mapped to facility + * + * + * created 2010-12-13 by David Lang based on pmlastmsg + * Modified 2017-05-29 by Shane Lawrence. + * + * This file is part of rsyslog. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * -or- + * see COPYING.ASL20 in the source distribution + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "msg.h" +#include "module-template.h" +#include "glbl.h" +#include "errmsg.h" +#include "parser.h" +#include "datetime.h" +#include "unicode-helper.h" +#include "rsconf.h" + +MODULE_TYPE_PARSER +MODULE_TYPE_NOKEEP +PARSER_NAME("rsyslog.snare") +MODULE_CNFNAME("pmsnare") + +/* internal structures + */ +DEF_PMOD_STATIC_DATA +DEFobjCurrIf(glbl) +DEFobjCurrIf(parser) +DEFobjCurrIf(datetime) + + +/* static data */ +static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ + +/* Keep a list of parser instances so we can apply global settings after config is loaded. */ +typedef struct modInstances_s { + instanceConf_t *root; + instanceConf_t *tail; +} modInstances_t; +static modInstances_t *modInstances = NULL; + +struct modConfData_s { + rsconf_t *pConf; /* our overall config object */ +}; +static modConfData_t *modConf = NULL; + +/* Per-instance config settings. */ +static struct cnfparamdescr parserpdescr[] = { + { "parser.controlcharacterescapeprefix", eCmdHdlrGetChar, 0 }, + { "parser.escapecontrolcharactersonreceive", eCmdHdlrBinary, 0 }, + { "parser.escapecontrolcharactertab", eCmdHdlrBinary, 0}, + { "parser.escapecontrolcharacterscstyle", eCmdHdlrBinary, 0 } +}; +static struct cnfparamblk parserpblk = { + CNFPARAMBLK_VERSION, + sizeof(parserpdescr)/sizeof(struct cnfparamdescr), + parserpdescr +}; +struct instanceConf_s { + int bEscapeCCOnRcv; + int bEscapeTab; + int bParserEscapeCCCStyle; + uchar cCCEscapeChar; + int tabLength; + char tabRepresentation[5]; + struct instanceConf_s *next; +}; + +/* Creates the instance and adds it to the list of instances. */ +static rsRetVal createInstance(instanceConf_t **pinst) { + instanceConf_t *inst; + DEFiRet; + CHKmalloc(inst = malloc(sizeof(instanceConf_t))); + inst->next = NULL; + *pinst = inst; + + /* Add to list of instances. */ + if(modInstances == NULL) { + CHKmalloc(modInstances = malloc(sizeof(modInstances_t))); + modInstances->tail = modInstances->root = NULL; + } + if (modInstances->tail == NULL) { + modInstances->tail = modInstances->root = inst; + } else { + modInstances->tail->next = inst; + modInstances->tail = inst; + } + + finalize_it: + RETiRet; +} + +BEGINnewParserInst + struct cnfparamvals *pvals = NULL; + int i; +CODESTARTnewParserInst + DBGPRINTF("newParserInst (pmsnare)\n"); + inst = NULL; + CHKiRet(createInstance(&inst)); + + /* Mark these as unset so we know if they should be overridden later. */ + inst->bEscapeCCOnRcv = -1; + inst->bEscapeTab = -1; + inst->bParserEscapeCCCStyle = -1; + inst->cCCEscapeChar = '\0'; + + /* If using the old config, just use global settings for each instance. */ + if (lst == NULL) + FINALIZE; + + /* If using the new config, process module settings for this instance. */ + if((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { + ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); + } + + if(Debug) { + dbgprintf("pmsnare: parser param blk:\n"); + cnfparamsPrint(&parserpblk, pvals); + } + + for(i = 0 ; i < parserpblk.nParams ; ++i) { + if(!pvals[i].bUsed) + continue; + if(!strcmp(parserpblk.descr[i].name, "parser.escapecontrolcharactersonreceive")) { + inst->bEscapeCCOnRcv = pvals[i].val.d.n; + } else if(!strcmp(parserpblk.descr[i].name, "parser.escapecontrolcharactertab")) { + inst->bEscapeTab = pvals[i].val.d.n; + } else if(!strcmp(parserpblk.descr[i].name, "parser.escapecontrolcharacterscstyle")) { + inst->bParserEscapeCCCStyle = pvals[i].val.d.n; + } else if(!strcmp(parserpblk.descr[i].name, "parser.controlcharacterescapeprefix")) { + inst->cCCEscapeChar = (uchar) *es_str2cstr(pvals[i].val.d.estr, NULL); + } else { + dbgprintf("pmsnare: program error, non-handled param '%s'\n", parserpblk.descr[i].name); + } + } + +finalize_it: +CODE_STD_FINALIZERnewParserInst + if(lst != NULL) + cnfparamvalsDestruct(pvals, &parserpblk); + if(iRet != RS_RET_OK) + free(inst); +ENDnewParserInst + +BEGINfreeParserInst +CODESTARTfreeParserInst + dbgprintf("pmsnare: free parser instance %p\n", pInst); +ENDfreeParserInst + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATUREAutomaticSanitazion) + iRet = RS_RET_OK; + if(eFeat == sFEATUREAutomaticPRIParsing) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + +/* Interface with the global config. */ +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad + modConf = pModConf; + pModConf->pConf = pConf; +ENDbeginCnfLoad + +BEGINsetModCnf +CODESTARTsetModCnf + /* Could use module-globals here, but not global globals. */ + (void) lst; +ENDsetModCnf + +BEGINendCnfLoad + instanceConf_t *inst; +CODESTARTendCnfLoad + dbgprintf("pmsnare: Begin endCnfLoad\n"); + /* Loop through each parser instance and apply global settings to any option that hasn't been overridden. + * This can't be done any earlier because the config wasn't fully loaded until now. */ + for(inst = modInstances->root; inst != NULL; inst = inst->next) { + if(inst->bEscapeCCOnRcv == -1) + inst->bEscapeCCOnRcv = glbl.GetParserEscapeControlCharactersOnReceive(modConf->pConf); + if(inst->bEscapeTab == -1) + inst->bEscapeTab = glbl.GetParserEscapeControlCharacterTab(modConf->pConf); + if(inst->bParserEscapeCCCStyle == -1) + inst->bParserEscapeCCCStyle = glbl.GetParserEscapeControlCharactersCStyle(modConf->pConf); + if(inst->cCCEscapeChar == '\0') + inst->cCCEscapeChar = glbl.GetParserControlCharacterEscapePrefix(modConf->pConf); + + /* Determine tab representation. Possible options: + * "#011" escape on, escapetabs on, no change to prefix (default) + * "?011" prefix changed in config + * "\\t" C style + * '\t' escape turned off + */ + if (inst->bEscapeCCOnRcv && inst->bEscapeTab) { + if (inst->bParserEscapeCCCStyle) { + strncpy(inst->tabRepresentation, "\\t", 5); + } else { + strncpy(inst->tabRepresentation, "#011", 5); + inst->tabRepresentation[0] = inst->cCCEscapeChar; + } + } else { + strncpy(inst->tabRepresentation, "\t", 5); + } + inst->tabLength=strlen(inst->tabRepresentation); + /* TODO: This debug message would be more useful if it told which Snare instance! */ + dbgprintf("pmsnare: Snare parser will treat '%s' as tab.\n", inst->tabRepresentation); + } + + assert(pModConf == modConf); +ENDendCnfLoad + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + +BEGINfreeCnf + instanceConf_t *inst, *del; +CODESTARTfreeCnf + for(inst = modInstances->root ; inst != NULL ; ) { + del = inst; + inst = inst->next; + free(del); + } + free(modInstances); +ENDfreeCnf + +BEGINparse2 + uchar *p2parse; + int lenMsg; + int snaremessage; /* 0 means not a snare message, otherwise it's the index of the tab after the tag */ + +CODESTARTparse2 + dbgprintf("Message will now be parsed by fix Snare parser.\n"); + assert(pMsg != NULL); + assert(pMsg->pszRawMsg != NULL); + + /* check if this message is of the type we handle in this (very limited) parser + * + * - Find out if the first separator is a tab. + * - If it is, see if the second word is one of our expected tags. + * - If so, flag as Snare and replace the first tab with space so that + * hostname and syslog tag are going to be parsed properly + * - Else not a snare message, abort. + * - Else assume valid 3164 timestamp, move over to the syslog tag. + * - See if syslog header is followed by tab and one of our expected tags. + * - If so, flag as Snare. + * - See if either type flagged as Snare. + * - If so, replace the tab with a space so that it will be parsed properly. + */ + + snaremessage=0; + /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ + lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; + /* point to start of text, after PRI */ + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; + dbgprintf("pmsnare: msg to look at: [%d]'%s'\n", lenMsg, p2parse); + if((unsigned) lenMsg < 30) { + /* too short, can not be "our" message */ + dbgprintf("pmsnare: Message is too short to be Snare!\n"); + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + + /* Find the first separator and check if it's a tab. */ + while(lenMsg && *p2parse != ' ' && *p2parse != '\t' && *p2parse != pInst->tabRepresentation[0]) { + --lenMsg; + ++p2parse; + } + if ((lenMsg > pInst->tabLength) && (strncasecmp((char *)p2parse, pInst->tabRepresentation, + pInst->tabLength) == 0)) { + dbgprintf("pmsnare: tab separated message\n"); + dbgprintf("pmsnare: tab [%d]'%s' msg at the first separator: [%d]'%s'\n", + pInst->tabLength, pInst->tabRepresentation, lenMsg, p2parse); + + /* Look for the Snare tag. */ + if(strncasecmp((char*)(p2parse + pInst->tabLength), "MSWinEventLog", 13) == 0) { + dbgprintf("Found a non-syslog Windows Snare message.\n"); + snaremessage = p2parse - pMsg->pszRawMsg + pInst->tabLength + 13; + } + else if(strncasecmp((char*) (p2parse + pInst->tabLength), "LinuxKAudit", 11) == 0) { + dbgprintf("Found a non-syslog Linux Snare message.\n"); + snaremessage = p2parse - pMsg->pszRawMsg + pInst->tabLength + 11; + } else { + /* Tab-separated but no Snare tag-> can't be Snare! */ + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + } + + /* This is a non-syslog Snare message. Example: + * other.lab.home MSWinEventLog 1 Security 606129 Wed May 17 02:25:10 2017 + */ + + /* Remove the tab between the hostname and Snare tag. */ + *p2parse = ' '; + p2parse++; + lenMsg--; + lenMsg -= (pInst->tabLength-1); /* size of tab goes from tabLength to 1, so shorten + the message by the difference */ + memmove(p2parse, p2parse+(pInst->tabLength-1), lenMsg); + /* move the message portion up to overwrite the tab */ + *(p2parse + lenMsg) = '\0'; + pMsg->iLenRawMsg -= (pInst->tabLength-1); + pMsg->iLenMSG -= (pInst->tabLength-1); + snaremessage -= (pInst->tabLength-1); + } else { + /* The first separator is not a tab. Look for a syslog Snare message. Example: + * <14>May 17 02:25:10 syslog.lab.home MSWinEventLog 1 Security 606129 + Wed May 17 02:25:10 2017 + */ + + /* go back to the beginning of the message */ + lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; + /* offAfterPRI is already the number of PRI chars (do not add one!) */ + p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; + + /* skip over timestamp and space (15 chars + space). */ + lenMsg -=16; + p2parse +=16; + /* skip over what should be the hostname and space */ + while(lenMsg && *p2parse != ' ') { + --lenMsg; + ++p2parse; + } + if (lenMsg){ + --lenMsg; + ++p2parse; + } + dbgprintf("pmsnare: tab [%d]'%s' msg after the timestamp and hostname: [%d]'%s'\n", + pInst->tabLength,pInst->tabRepresentation,lenMsg, p2parse); + + /* Look for the Snare tag. */ + if(lenMsg > 13 && strncasecmp((char*) p2parse, "MSWinEventLog", 13) == 0) { + dbgprintf("Found a syslog Windows Snare message.\n"); + snaremessage = p2parse - pMsg->pszRawMsg + 13; + } + else if(lenMsg > 11 && strncasecmp((char*) p2parse, "LinuxKAudit", 11) == 0) { + dbgprintf("pmsnare: Found a syslog Linux Snare message.\n"); + snaremessage = p2parse - pMsg->pszRawMsg + 11; + } + } + + if(snaremessage) { + /* Skip to the end of the tag. */ + p2parse = pMsg->pszRawMsg + snaremessage; + lenMsg = pMsg->iLenRawMsg - snaremessage; + + /* Remove the tab after the tag. */ + *p2parse = ' '; + p2parse++; + lenMsg--; + lenMsg -= (pInst->tabLength-1); /* size of tab goes from tabLength to 1, so shorten + the message by the difference */ + memmove(p2parse, p2parse+(pInst->tabLength-1), lenMsg); + /* move the message portion up to overwrite the tab */ + *(p2parse + lenMsg) = '\0'; + pMsg->iLenRawMsg -= (pInst->tabLength-1); + pMsg->iLenMSG -= (pInst->tabLength-1); + + DBGPRINTF("pmsnare: new message: [%d]'%s'\n", lenMsg, pMsg->pszRawMsg + pMsg->offAfterPRI); + } + + ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); + +finalize_it: +ENDparse2 + +BEGINmodExit +CODESTARTmodExit + /* release what we no longer need */ + objRelease(glbl, CORE_COMPONENT); + objRelease(parser, CORE_COMPONENT); + objRelease(datetime, CORE_COMPONENT); +ENDmodExit + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_MOD_QUERIES +CODEqueryEtryPt_STD_CONF2_QUERIES +CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES +CODEqueryEtryPt_STD_PMOD2_QUERIES +CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES +ENDqueryEtryPt + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(parser, CORE_COMPONENT)); + CHKiRet(objUse(datetime, CORE_COMPONENT)); + + DBGPRINTF("snare parser init called, compiled with version %s\n", VERSION); + bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); + /* cache value, is set only during rsyslogd option processing */ +ENDmodInit + +/* vim:set ai: + */ |