summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/README12
-rw-r--r--contrib/ffaup/Makefile.am8
-rw-r--r--contrib/ffaup/Makefile.in801
-rw-r--r--contrib/ffaup/ffaup.c395
-rw-r--r--contrib/fmhash/Makefile.am8
-rw-r--r--contrib/fmhash/Makefile.in801
-rw-r--r--contrib/fmhash/fmhash.c384
-rw-r--r--contrib/fmunflatten/Makefile.am5
-rw-r--r--contrib/fmunflatten/Makefile.in797
-rw-r--r--contrib/fmunflatten/fmunflatten.c243
-rw-r--r--contrib/gnutls/ca.pem15
-rw-r--r--contrib/gnutls/cert.pem16
-rw-r--r--contrib/gnutls/key.pem15
-rw-r--r--contrib/imbatchreport/Makefile.am6
-rw-r--r--contrib/imbatchreport/Makefile.in797
-rw-r--r--contrib/imbatchreport/imbatchreport.c1033
-rw-r--r--contrib/imczmq/Makefile.am8
-rw-r--r--contrib/imczmq/Makefile.in798
-rw-r--r--contrib/imczmq/README39
-rw-r--r--contrib/imczmq/imczmq.c632
-rw-r--r--contrib/imdocker/Makefile.am6
-rw-r--r--contrib/imdocker/Makefile.in797
-rw-r--r--contrib/imdocker/imdocker.c1794
-rw-r--r--contrib/imhiredis/COPYING674
-rw-r--r--contrib/imhiredis/Makefile.am7
-rw-r--r--contrib/imhiredis/Makefile.in799
-rw-r--r--contrib/imhiredis/README81
-rw-r--r--contrib/imhiredis/imhiredis.c2298
-rw-r--r--contrib/imhttp/Makefile.am5
-rw-r--r--contrib/imhttp/Makefile.in795
-rw-r--r--contrib/imhttp/imhttp.c1326
-rw-r--r--contrib/imkmsg/Makefile.am8
-rw-r--r--contrib/imkmsg/Makefile.in807
-rw-r--r--contrib/imkmsg/imkmsg.c372
-rw-r--r--contrib/imkmsg/imkmsg.h78
-rw-r--r--contrib/imkmsg/kmsg.c327
-rw-r--r--contrib/impcap/Makefile.am22
-rw-r--r--contrib/impcap/Makefile.in949
-rw-r--r--contrib/impcap/arp_parser.c163
-rw-r--r--contrib/impcap/dns_parser.c372
-rw-r--r--contrib/impcap/eth_parser.c179
-rw-r--r--contrib/impcap/ftp_parser.c152
-rw-r--r--contrib/impcap/http_parser.c159
-rw-r--r--contrib/impcap/icmp_parser.c79
-rw-r--r--contrib/impcap/impcap.c748
-rw-r--r--contrib/impcap/ipv4_parser.c101
-rw-r--r--contrib/impcap/ipv6_parser.c305
-rw-r--r--contrib/impcap/ipx_parser.c97
-rw-r--r--contrib/impcap/llc_parser.c109
-rw-r--r--contrib/impcap/parsers.h189
-rw-r--r--contrib/impcap/smb_parser.c145
-rw-r--r--contrib/impcap/tcp_parser.c121
-rw-r--r--contrib/impcap/udp_parser.c90
-rw-r--r--contrib/improg/Makefile.am11
-rw-r--r--contrib/improg/Makefile.in799
-rw-r--r--contrib/improg/improg.c722
-rw-r--r--contrib/imtuxedoulog/Makefile.am13
-rw-r--r--contrib/imtuxedoulog/Makefile.in799
-rw-r--r--contrib/imtuxedoulog/imtuxedoulog.c860
-rw-r--r--contrib/mmcount/Makefile.am8
-rw-r--r--contrib/mmcount/Makefile.in797
-rw-r--r--contrib/mmcount/mmcount.c351
-rw-r--r--contrib/mmdarwin/Makefile.am8
-rw-r--r--contrib/mmdarwin/Makefile.in797
-rw-r--r--contrib/mmdarwin/mmdarwin.c953
-rw-r--r--contrib/mmdarwin/protocol.h70
-rw-r--r--contrib/mmgrok/Makefile.am8
-rw-r--r--contrib/mmgrok/Makefile.in798
-rw-r--r--contrib/mmgrok/README32
-rw-r--r--contrib/mmgrok/mmgrok.c418
-rw-r--r--contrib/mmkubernetes/Makefile.am8
-rw-r--r--contrib/mmkubernetes/Makefile.in800
-rw-r--r--contrib/mmkubernetes/k8s_container_name.rulebase3
-rw-r--r--contrib/mmkubernetes/k8s_filename.rulebase2
-rw-r--r--contrib/mmkubernetes/mmkubernetes.c2085
-rw-r--r--contrib/mmrfc5424addhmac/Makefile.am8
-rw-r--r--contrib/mmrfc5424addhmac/Makefile.in801
-rw-r--r--contrib/mmrfc5424addhmac/mmrfc5424addhmac.c382
-rw-r--r--contrib/mmsequence/Makefile.am8
-rw-r--r--contrib/mmsequence/Makefile.in797
-rw-r--r--contrib/mmsequence/mmsequence.c406
-rw-r--r--contrib/mmtaghostname/Makefile.am8
-rw-r--r--contrib/mmtaghostname/Makefile.in798
-rw-r--r--contrib/mmtaghostname/mmtaghostname.c205
-rw-r--r--contrib/omamqp1/Makefile.am8
-rw-r--r--contrib/omamqp1/Makefile.in798
-rw-r--r--contrib/omamqp1/omamqp1.c921
-rw-r--r--contrib/omczmq/Makefile.am8
-rw-r--r--contrib/omczmq/Makefile.in798
-rw-r--r--contrib/omczmq/README79
-rw-r--r--contrib/omczmq/omczmq.c652
-rw-r--r--contrib/omfile-hardened/Makefile.am8
-rw-r--r--contrib/omfile-hardened/Makefile.in799
-rw-r--r--contrib/omfile-hardened/omfile-hardened.c1654
-rw-r--r--contrib/omhiredis/COPYING674
-rw-r--r--contrib/omhiredis/Makefile.am7
-rw-r--r--contrib/omhiredis/Makefile.in799
-rw-r--r--contrib/omhiredis/README70
-rw-r--r--contrib/omhiredis/omhiredis.c753
-rw-r--r--contrib/omhttp/Makefile.am8
-rw-r--r--contrib/omhttp/Makefile.in798
-rw-r--r--contrib/omhttp/omhttp.c2212
-rw-r--r--contrib/omhttpfs/Makefile.am9
-rw-r--r--contrib/omhttpfs/Makefile.in798
-rw-r--r--contrib/omhttpfs/omhttpfs.c855
-rw-r--r--contrib/omrabbitmq/Makefile.am8
-rw-r--r--contrib/omrabbitmq/Makefile.in798
-rw-r--r--contrib/omrabbitmq/omrabbitmq.c1381
-rw-r--r--contrib/omtcl/Makefile.am8
-rw-r--r--contrib/omtcl/Makefile.in798
-rw-r--r--contrib/omtcl/omtcl.c164
-rw-r--r--contrib/pmaixforwardedfrom/Makefile.am8
-rw-r--r--contrib/pmaixforwardedfrom/Makefile.in800
-rw-r--r--contrib/pmaixforwardedfrom/pmaixforwardedfrom.c185
-rw-r--r--contrib/pmcisconames/Makefile.am8
-rw-r--r--contrib/pmcisconames/Makefile.in798
-rw-r--r--contrib/pmcisconames/pmcisconames.c185
-rw-r--r--contrib/pmdb2diag/Makefile.am8
-rw-r--r--contrib/pmdb2diag/Makefile.in797
-rw-r--r--contrib/pmdb2diag/pmdb2diag.c305
-rw-r--r--contrib/pmpanngfw/Makefile.am8
-rw-r--r--contrib/pmpanngfw/Makefile.in797
-rw-r--r--contrib/pmpanngfw/pmpanngfw.c296
-rw-r--r--contrib/pmsnare/Makefile.am8
-rw-r--r--contrib/pmsnare/Makefile.in797
-rw-r--r--contrib/pmsnare/pmsnare.c444
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:
+ */