commit 69e42aac8da3ecf7fd56fe627570f9d9e552c009 Author: Phillip Smith Date: Tue Aug 24 17:55:37 2021 +1000 initial commit diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5874479 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,26 @@ +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + + +SUBDIRS = src diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..8eb4682 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,820 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 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@ + +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. +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 = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_asio.m4 \ + $(top_srcdir)/m4/ax_boost_base.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/standalone/config_files.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +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 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# 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 +CSCOPE = cscope +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in ar-lib \ + compile config.guess config.sub install-sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BOOST_ASIO_LIB = @BOOST_ASIO_LIB@ +BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ +BOOST_LDFLAGS = @BOOST_LDFLAGS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_CXX17 = @HAVE_CXX17@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +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@ +RANLIB = @RANLIB@ +RE2_CPPFLAGS = @RE2_CPPFLAGS@ +RE2_LDFLAGS = @RE2_LDFLAGS@ +RE2_LIBS = @RE2_LIBS@ +RRDLIB = @RRDLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +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_CXX = @ac_ct_CXX@ +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@ +nagios_headers = @nagios_headers@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +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@ +SUBDIRS = src +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(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-recursive + +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" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +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 + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +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-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck 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-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.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/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..afe5cbd --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1215 @@ +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. + +# This file 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. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_PROG_AR([ACT-IF-FAIL]) +# ------------------------- +# Try to determine the archiver interface, and trigger the ar-lib wrapper +# if it is needed. If the detection of archiver interface fails, run +# ACT-IF-FAIL (default is to abort configure with a proper error message). +AC_DEFUN([AM_PROG_AR], +[AC_BEFORE([$0], [LT_INIT])dnl +AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([ar-lib])dnl +AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) +: ${AR=ar} + +AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], + [AC_LANG_PUSH([C]) + am_cv_ar_interface=ar + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], + [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + ]) + AC_LANG_POP([C])]) + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + m4_default([$1], + [AC_MSG_ERROR([could not determine $AR interface])]) + ;; +esac +AC_SUBST([AR])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file 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. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file 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. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file 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. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file 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 macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# +# This file 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. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file 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. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# +# This file 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. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# +# This file 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. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# +# This file 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. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# +# This file 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. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/ax_boost_asio.m4]) +m4_include([m4/ax_boost_base.m4]) +m4_include([m4/ax_cxx_compile_stdcxx.m4]) diff --git a/api/c++/Livestatus.cc b/api/c++/Livestatus.cc new file mode 100644 index 0000000..782a044 --- /dev/null +++ b/api/c++/Livestatus.cc @@ -0,0 +1,87 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// ails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Livestatus.h" +#include +#include +#include +#include +#include + +void Livestatus::connectUNIX(const char *socket_path) { + _connection = socket(PF_LOCAL, SOCK_STREAM, 0); + struct sockaddr_un sockaddr; + sockaddr.sun_family = AF_UNIX; + strncpy(sockaddr.sun_path, socket_path, sizeof(sockaddr.sun_path) - 1); + sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0'; + if (0 > connect(_connection, (const struct sockaddr *)&sockaddr, + sizeof(sockaddr))) { + close(_connection); + _connection = -1; + } else + _file = fdopen(_connection, "r"); +} + +Livestatus::~Livestatus() { disconnect(); } + +void Livestatus::disconnect() { + if (isConnected()) { + if (_file) + fclose(_file); + else + close(_connection); + } + _connection = -1; + _file = 0; +} + +void Livestatus::sendQuery(const char *query) { + write(_connection, query, strlen(query)); + std::string separators = "Separators: 10 1 2 3\n"; + write(_connection, separators.c_str(), separators.size()); + shutdown(_connection, SHUT_WR); +} + +std::vector *Livestatus::nextRow() { + char line[65536]; + if (0 != fgets(line, sizeof(line), _file)) { + // strip trailing linefeed + char *end = strlen(line) + line; + if (end > line && *(end - 1) == '\n') { + *(end - 1) = 0; + --end; + } + std::vector *row = new std::vector; + char *scan = line; + while (scan < end) { + char *zero = scan; + while (zero < end && *zero != '\001') zero++; + *zero = 0; + row->push_back(std::string(scan)); + scan = zero + 1; + } + return row; + } else + return 0; +} diff --git a/api/c++/Livestatus.h b/api/c++/Livestatus.h new file mode 100644 index 0000000..c176b15 --- /dev/null +++ b/api/c++/Livestatus.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// ails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Livestatus_h +#define Livestatus_h + +#include +#include +#include + +// simple C++ API for accessing Livestatus from C++, +// currently supports only UNIX sockets, no TCP. But +// this is only a simple enhancement. + +class Livestatus { + int _connection; + FILE *_file; + +public: + Livestatus() : _connection(-1), _file(0){}; + ~Livestatus(); + void connectUNIX(const char *socketpath); + bool isConnected() const { return _connection >= 0; }; + void disconnect(); + void sendQuery(const char *query); + std::vector *nextRow(); +}; + +#endif // Livestatus_h diff --git a/api/c++/Makefile b/api/c++/Makefile new file mode 100644 index 0000000..b1c7ffe --- /dev/null +++ b/api/c++/Makefile @@ -0,0 +1,42 @@ +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +ifneq (DEBUG,) + CXXFLAGS += -g -DDEBUG + LDFLAGS += -g +endif + +all: demo + +demo.o: demo.cc Livestatus.h + $(CXX) $(CXXFLAGS) -c -o $@ $< + +Livestatus.o: Livestatus.cc Livestatus.h + $(CXX) $(CXXFLAGS) -c -o $@ $< + +demo: demo.o Livestatus.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ + +clean: + $(RM) demo.o demo Livetatus.o diff --git a/api/c++/demo.cc b/api/c++/demo.cc new file mode 100644 index 0000000..455a203 --- /dev/null +++ b/api/c++/demo.cc @@ -0,0 +1,54 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// ails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include +#include "Livestatus.h" + +const char *query = + "GET status\nColumns: livestatus_version program_version\nColumnHeaders: on\n"; + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s SOCKETPATH\n", argv[0]); + return 1; + } + + const char *socket_path = argv[1]; + Livestatus live; + live.connectUNIX(socket_path); + if (live.isConnected()) { + fprintf(stderr, "Couldn't connect to socket '%s'\n", socket_path); + return 1; + } + live.sendQuery(query); + std::vector *row; + while (0 != (row = live.nextRow())) { + printf("Line:\n"); + for (size_t i = 0; i < row->size(); i++) + printf("%s\n", (*row)[i].c_str()); + delete row; + } + live.disconnect(); + return 0; +} diff --git a/api/perl/Changes b/api/perl/Changes new file mode 100644 index 0000000..d6cfd73 --- /dev/null +++ b/api/perl/Changes @@ -0,0 +1,164 @@ +Revision history for Perl extension Monitoring::Livestatus. + + +0.74 Fri Apr 22 00:16:37 CEST 2011 + - fixed problem with bulk commands + +0.72 Tue Apr 19 15:38:34 CEST 2011 + - fixed problem with inet timeout + +0.70 Sat Apr 16 16:43:57 CEST 2011 + - fixed tests using english + +0.68 Wed Mar 23 23:16:22 CET 2011 + - fixed typo + +0.66 Tue Mar 22 23:19:23 CET 2011 + - added support for additonal headers + +0.64 Fri Nov 5 11:02:51 CET 2010 + - removed useless test dependecies + +0.62 Wed Nov 3 15:20:02 CET 2010 + - fixed tests with threads > 1.79 + +0.60 Wed Aug 25 15:04:22 CEST 2010 + - fixed package and made author tests optional + +0.58 Wed Aug 11 09:30:30 CEST 2010 + - added callback support + +0.56 Tue Aug 10 09:45:28 CEST 2010 + - changed parser from csv to JSON::XS + +0.54 Wed Jun 23 16:43:11 CEST 2010 + - fixed utf8 support + +0.52 Mon May 17 15:54:42 CEST 2010 + - fixed connection timeout + +0.50 Mon May 17 12:29:20 CEST 2010 + - fixed test requirements + +0.48 Sun May 16 15:16:12 CEST 2010 + - added retry option for better core restart handling + - added new columns from livestatus 1.1.4 + +0.46 Tue Mar 16 15:19:08 CET 2010 + - error code have been changed in livestatus (1.1.3) + - fixed threads support + +0.44 Sun Feb 28 12:19:56 CET 2010 + - fixed bug when disabling backends and using threads + +0.42 Thu Feb 25 21:32:37 CET 2010 + - added possibility to disable specific backends + +0.41 Sat Feb 20 20:37:36 CET 2010 + - fixed tests on windows + +0.40 Thu Feb 11 01:00:20 CET 2010 + - fixed timeout for inet sockets + +0.38 Fri Jan 29 20:54:50 CET 2010 + - added limit option + +0.37 Thu Jan 28 21:23:19 CET 2010 + - removed inc from repository + +0.36 Sun Jan 24 00:14:13 CET 2010 + - added more backend tests + - fixed problem with summing up non numbers + +0.35 Mon Jan 11 15:37:51 CET 2010 + - added TCP_NODELAY option for inet sockets + - fixed undefined values + +0.34 Sun Jan 10 12:29:57 CET 2010 + - fixed return code with multi backend and different errors + +0.32 Sat Jan 9 16:12:48 CET 2010 + - added deepcopy option + +0.31 Thu Jan 7 08:56:48 CET 2010 + - added generic tests for livestatus backend + - fixed problem when selecting specific backend + +0.30 Wed Jan 6 16:05:33 CET 2010 + - renamed project to Monitoring::Livestatus + +0.29 Mon Dec 28 00:11:53 CET 2009 + - retain order of backends when merge outut + - renamed select_scalar_value to selectscalar_value + - fixed sums for selectscalar_value + - fixed missing META.yml + +0.28 Sat Dec 19 19:19:13 CET 2009 + - fixed bug in column alias + - added support for multiple peers + - changed to Module::Install + +0.26 Fri Dec 4 08:25:07 CET 2009 + - added peer name + - added peer arg (can be socket or server) + +0.24 Wed Dec 2 23:41:34 CET 2009 + - added support for StatsAnd: and StatsOr: queries + - table alias support for selectall_hashref and selectrow_hashref + - added support for Stats: ... as alias + - added support for StatsAnd:... as alias + - added support for StatsOr: ... as alias + - added support for StatsGroupBy: (with alias) + - added support column aliases for Column: header + +0.22 Fri Nov 27 01:04:16 CET 2009 + - fixed errors on socket problems + - fixed sending commands + +0.20 Sun Nov 22 12:41:39 CET 2009 + - added keepalive support + - added support for ResponseHeader: fixed16 + - added error handling + - added pod test + - added tests with real socket / server + - added column aliases + - added timeout option + - implemented select_scalar_value() + - fixed perl::critic tests + +0.18 Sat Nov 14 2009 08:58:02 GMT + - fixed requirements + - fixed typos + +0.17 Fri Nov 13 17:15:44 CET 2009 + - added support for tcp connections + +0.16 Sun Nov 8 23:17:35 CET 2009 + - added support for stats querys + +0.15 Sat Nov 7 21:28:33 CET 2009 + - fixed typos in doc + - minor bugfixes + +0.14 Fri Nov 6 09:39:56 CET 2009 + - implemented selectcol_arrayref + - implemented selectrow_array + - implemented selectrow_hashref + +0.13 Fri Nov 6 00:03:38 CET 2009 + - fixed tests on solaris + - implemented selectall_hashref() + +0.12 Thu Nov 5 09:34:59 CET 2009 + - fixed tests with thread support + - added more tests + +0.11 Wed Nov 4 23:12:16 2009 + - inital working version + +0.10 Tue Nov 3 17:13:16 2009 + - renamed to Nagios::MKLivestatus + +0.01 Tue Nov 3 00:07:46 2009 + - original version; created by h2xs 1.23 with options + -A -X -n Nagios::Livestatus diff --git a/api/perl/MANIFEST b/api/perl/MANIFEST new file mode 100644 index 0000000..c0a5740 --- /dev/null +++ b/api/perl/MANIFEST @@ -0,0 +1,38 @@ +Changes +examples/dump.pl +examples/test.pl +inc/Module/AutoInstall.pm +inc/Module/Install.pm +inc/Module/Install/AutoInstall.pm +inc/Module/Install/Base.pm +inc/Module/Install/Can.pm +inc/Module/Install/Fetch.pm +inc/Module/Install/Include.pm +inc/Module/Install/Makefile.pm +inc/Module/Install/Metadata.pm +inc/Module/Install/Win32.pm +inc/Module/Install/WriteAll.pm +lib/Monitoring/Livestatus.pm +lib/Monitoring/Livestatus/INET.pm +lib/Monitoring/Livestatus/MULTI.pm +lib/Monitoring/Livestatus/UNIX.pm +Makefile.PL +MANIFEST This list of files +META.yml +README +t/01-Monitoring-Livestatus-basic_tests.t +t/02-Monitoring-Livestatus-internals.t +t/03-Monitoring-Livestatus-MULTI-internals.t +t/20-Monitoring-Livestatus-test_socket.t +t/21-Monitoring-Livestatus-INET.t +t/22-Monitoring-Livestatus-UNIX.t +t/30-Monitoring-Livestatus-live-test.t +t/31-Monitoring-Livestatus-MULTI-live-test.t +t/32-Monitoring-Livestatus-backend-test.t +t/33-Monitoring-Livestatus-test_socket_timeout.t +t/34-Monitoring-Livestatus-utf8_support.t +t/35-Monitoring-Livestatus-callbacks_support.t +t/97-Pod.t +t/98-Pod-Coverage.t +t/99-Perl-Critic.t +t/perlcriticrc diff --git a/api/perl/META.yml b/api/perl/META.yml new file mode 100644 index 0000000..9def198 --- /dev/null +++ b/api/perl/META.yml @@ -0,0 +1,37 @@ +--- +abstract: 'Perl API for check_mk livestatus to access runtime' +author: + - 'Sven Nierlein, ' +build_requires: + ExtUtils::MakeMaker: 6.42 +configure_requires: + ExtUtils::MakeMaker: 6.42 +distribution_type: module +generated_by: 'Module::Install version 1.00' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 +name: Monitoring-Livestatus +no_index: + directory: + - examples + - inc + - t +requires: + Digest::MD5: 0 + Encode: 0 + IO::Socket::INET: 0 + IO::Socket::UNIX: 0 + JSON::XS: 0 + Scalar::Util: 0 + Test::More: 0.87 + Thread::Queue: 2.11 + perl: 5.6.0 + utf8: 0 +resources: + bugtracker: http://github.com/sni/Monitoring-Livestatus/issues + homepage: http://search.cpan.org/dist/Monitoring-Livestatus/ + license: http://dev.perl.org/licenses/ + repository: http://github.com/sni/Monitoring-Livestatus +version: 0.74 diff --git a/api/perl/Makefile.PL b/api/perl/Makefile.PL new file mode 100644 index 0000000..ac02e63 --- /dev/null +++ b/api/perl/Makefile.PL @@ -0,0 +1,41 @@ +# IMPORTANT: if you delete this file your app will not work as +# expected. you have been warned +use inc::Module::Install; + +name 'Monitoring-Livestatus'; +all_from 'lib/Monitoring/Livestatus.pm'; +perl_version '5.006'; +license 'perl'; + +resources( + 'homepage', => 'http://search.cpan.org/dist/Monitoring-Livestatus/', + 'bugtracker' => 'http://github.com/sni/Monitoring-Livestatus/issues', + 'repository', => 'http://github.com/sni/Monitoring-Livestatus', +); + + +requires 'IO::Socket::UNIX'; +requires 'IO::Socket::INET'; +requires 'Digest::MD5'; +requires 'Scalar::Util'; +requires 'Test::More' => '0.87'; +requires 'Thread::Queue' => '2.11'; +requires 'utf8'; +requires 'Encode'; +requires 'JSON::XS'; + +# test requirements +# these requirements still make it into the META.yml, so they are commented so far +#feature ('authortests', +# -default => 0, +# 'File::Copy::Recursive' => 0, +# 'Test::Pod' => 1.14, +# 'Test::Perl::Critic' => 0, +# 'Test::Pod::Coverage' => 0, +# 'Perl::Critic::Policy::Dynamic::NoIndirect' => 0, +# 'Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseSubs' => 0, +# 'Perl::Critic::Policy::ValuesAndExpressions::ProhibitAccessOfPrivateData' => 0, +#); + +auto_install; +WriteAll; diff --git a/api/perl/README b/api/perl/README new file mode 100644 index 0000000..40649df --- /dev/null +++ b/api/perl/README @@ -0,0 +1,32 @@ +Monitoring-Livestatus +===================== + + Monitoring::Livestatus can be used to access the data of the check_mk + Livestatus Addon for Nagios and Icinga. + +INSTALLATION + + To install this module type the following: + + perl Makefile.PL + make + make test + make install + +DEPENDENCIES + + This module requires no other modules. + +SYNOPSIS + my $ml = Monitoring::Livestatus->new( socket => '/var/lib/livestatus/livestatus.sock' ); + my $hosts = $ml->selectall_arrayref("GET hosts"); + +AUTHOR + Sven Nierlein + +COPYRIGHT AND LICENCE + + Copyright (C) 2009 by Sven Nierlein + + This library is free software; you can redistribute it and/or modify + it under the same terms as Perl itself. diff --git a/api/perl/examples/dump.pl b/api/perl/examples/dump.pl new file mode 100755 index 0000000..a0337cd --- /dev/null +++ b/api/perl/examples/dump.pl @@ -0,0 +1,104 @@ +#!/usr/bin/env perl + +=head1 NAME + +dump.pl - print some information from a socket + +=head1 SYNOPSIS + +./dump.pl [ -h ] [ -v ] + +=head1 DESCRIPTION + +this script print some information from a given livestatus socket or server + +=head1 ARGUMENTS + +script has the following arguments + +=over 4 + +=item help + + -h + +print help and exit + +=item verbose + + -v + +verbose output + +=item socket/server + + server local socket file or + + server remote address of livestatus + +=back + +=head1 EXAMPLE + +./dump.pl /tmp/live.sock + +=head1 AUTHOR + +2009, Sven Nierlein, + +=cut + +use warnings; +use strict; +use Data::Dumper; +use Getopt::Long; +use Pod::Usage; +use lib 'lib'; +use lib '../lib'; +use Monitoring::Livestatus; + +$Data::Dumper::Sortkeys = 1; + +######################################################################### +# parse and check cmd line arguments +my ($opt_h, $opt_v, $opt_f); +Getopt::Long::Configure('no_ignore_case'); +if(!GetOptions ( + "h" => \$opt_h, + "v" => \$opt_v, + "<>" => \&add_file, +)) { + pod2usage( { -verbose => 1, -message => 'error in options' } ); + exit 3; +} + +if(defined $opt_h) { + pod2usage( { -verbose => 1 } ); + exit 3; +} +my $verbose = 0; +if(defined $opt_v) { + $verbose = 1; +} + +if(!defined $opt_f) { + pod2usage( { -verbose => 1, -message => 'socket/server is a required option' } ); + exit 3; +} + +######################################################################### +my $nl = Monitoring::Livestatus->new( peer => $opt_f, verbose => $opt_v ); + +######################################################################### +#my $hosts = $nl->selectall_hashref('GET hosts', 'name'); +#print Dumper($hosts); + +######################################################################### +my $services = $nl->selectall_arrayref("GET services\nColumns: description host_name state\nLimit: 2", { Slice => {}}); +print Dumper($services); + +######################################################################### +sub add_file { + my $file = shift; + $opt_f = $file; +} diff --git a/api/perl/examples/test.pl b/api/perl/examples/test.pl new file mode 100755 index 0000000..93a13a0 --- /dev/null +++ b/api/perl/examples/test.pl @@ -0,0 +1,143 @@ +#!/usr/bin/env perl + +=head1 NAME + +test.pl - print some information from a socket + +=head1 SYNOPSIS + +./test.pl [ -h ] [ -v ] + +=head1 DESCRIPTION + +this script print some information from a given livestatus socket or server + +=head1 ARGUMENTS + +script has the following arguments + +=over 4 + +=item help + + -h + +print help and exit + +=item verbose + + -v + +verbose output + +=item socket/server + + server local socket file or + + server remote address of livestatus + +=back + +=head1 EXAMPLE + +./test.pl /tmp/live.sock + +=head1 AUTHOR + +2009, Sven Nierlein, + +=cut + +use warnings; +use strict; +use Data::Dumper; +use Getopt::Long; +use Pod::Usage; +use Time::HiRes qw( gettimeofday tv_interval ); +use Log::Log4perl qw(:easy); +use lib 'lib'; +use lib '../lib'; +use Monitoring::Livestatus; + +$Data::Dumper::Sortkeys = 1; + +######################################################################### +# parse and check cmd line arguments +my ($opt_h, $opt_v, @opt_f); +Getopt::Long::Configure('no_ignore_case'); +if(!GetOptions ( + "h" => \$opt_h, + "v" => \$opt_v, + "<>" => \&add_file, +)) { + pod2usage( { -verbose => 1, -message => 'error in options' } ); + exit 3; +} + +if(defined $opt_h) { + pod2usage( { -verbose => 1 } ); + exit 3; +} +my $verbose = 0; +if(defined $opt_v) { + $verbose = 1; +} + +if(scalar @opt_f == 0) { + pod2usage( { -verbose => 1, -message => 'socket/server is a required option' } ); + exit 3; +} + +######################################################################### +Log::Log4perl->easy_init($DEBUG); +my $nl = Monitoring::Livestatus->new( + peer => \@opt_f, + verbose => $opt_v, + timeout => 5, + keepalive => 1, + logger => get_logger(), + ); +my $log = get_logger(); + +######################################################################### +my $querys = [ + { 'query' => "GET hostgroups\nColumns: members\nFilter: name = flap\nFilter: name = down\nOr: 2", + 'sub' => "selectall_arrayref", + 'opt' => {Slice => 1 } + }, +# { 'query' => "GET comments", +# 'sub' => "selectall_arrayref", +# 'opt' => {Slice => 1 } +# }, +# { 'query' => "GET downtimes", +# 'sub' => "selectall_arrayref", +# 'opt' => {Slice => 1, Sum => 1} +# }, +# { 'query' => "GET log\nFilter: time > ".(time() - 600)."\nLimit: 1", +# 'sub' => "selectall_arrayref", +# 'opt' => {Slice => 1, AddPeer => 1} +# }, +# { 'query' => "GET services\nFilter: contacts >= test\nFilter: host_contacts >= test\nOr: 2\nColumns: host_name description contacts host_contacts", +# 'sub' => "selectall_arrayref", +# 'opt' => {Slice => 1, AddPeer => 0} +# }, +# { 'query' => "GET services\nFilter: host_name = test_host_00\nFilter: description = test_flap_02\nOr: 2\nColumns: host_name description contacts host_contacts", +# 'sub' => "selectall_arrayref", +# 'opt' => {Slice => 1, AddPeer => 0} +# }, +]; +for my $query (@{$querys}) { + my $sub = $query->{'sub'}; + my $t0 = [gettimeofday]; + my $stats = $nl->$sub($query->{'query'}, $query->{'opt'}); + my $elapsed = tv_interval($t0); + print Dumper($stats); + print "Query took ".($elapsed)." seconds\n"; +} + + +######################################################################### +sub add_file { + my $file = shift; + push @opt_f, $file; +} diff --git a/api/perl/inc/Module/AutoInstall.pm b/api/perl/inc/Module/AutoInstall.pm new file mode 100644 index 0000000..60b90ea --- /dev/null +++ b/api/perl/inc/Module/AutoInstall.pm @@ -0,0 +1,820 @@ +#line 1 +package Module::AutoInstall; + +use strict; +use Cwd (); +use ExtUtils::MakeMaker (); + +use vars qw{$VERSION}; +BEGIN { + $VERSION = '1.03'; +} + +# special map on pre-defined feature sets +my %FeatureMap = ( + '' => 'Core Features', # XXX: deprecated + '-core' => 'Core Features', +); + +# various lexical flags +my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $HasCPANPLUS ); +my ( + $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps +); +my ( $PostambleActions, $PostambleUsed ); + +# See if it's a testing or non-interactive session +_accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN ); +_init(); + +sub _accept_default { + $AcceptDefault = shift; +} + +sub missing_modules { + return @Missing; +} + +sub do_install { + __PACKAGE__->install( + [ + $Config + ? ( UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) + : () + ], + @Missing, + ); +} + +# initialize various flags, and/or perform install +sub _init { + foreach my $arg ( + @ARGV, + split( + /[\s\t]+/, + $ENV{PERL_AUTOINSTALL} || $ENV{PERL_EXTUTILS_AUTOINSTALL} || '' + ) + ) + { + if ( $arg =~ /^--config=(.*)$/ ) { + $Config = [ split( ',', $1 ) ]; + } + elsif ( $arg =~ /^--installdeps=(.*)$/ ) { + __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) ); + exit 0; + } + elsif ( $arg =~ /^--default(?:deps)?$/ ) { + $AcceptDefault = 1; + } + elsif ( $arg =~ /^--check(?:deps)?$/ ) { + $CheckOnly = 1; + } + elsif ( $arg =~ /^--skip(?:deps)?$/ ) { + $SkipInstall = 1; + } + elsif ( $arg =~ /^--test(?:only)?$/ ) { + $TestOnly = 1; + } + elsif ( $arg =~ /^--all(?:deps)?$/ ) { + $AllDeps = 1; + } + } +} + +# overrides MakeMaker's prompt() to automatically accept the default choice +sub _prompt { + goto &ExtUtils::MakeMaker::prompt unless $AcceptDefault; + + my ( $prompt, $default ) = @_; + my $y = ( $default =~ /^[Yy]/ ); + + print $prompt, ' [', ( $y ? 'Y' : 'y' ), '/', ( $y ? 'n' : 'N' ), '] '; + print "$default\n"; + return $default; +} + +# the workhorse +sub import { + my $class = shift; + my @args = @_ or return; + my $core_all; + + print "*** $class version " . $class->VERSION . "\n"; + print "*** Checking for Perl dependencies...\n"; + + my $cwd = Cwd::cwd(); + + $Config = []; + + my $maxlen = length( + ( + sort { length($b) <=> length($a) } + grep { /^[^\-]/ } + map { + ref($_) + ? ( ( ref($_) eq 'HASH' ) ? keys(%$_) : @{$_} ) + : '' + } + map { +{@args}->{$_} } + grep { /^[^\-]/ or /^-core$/i } keys %{ +{@args} } + )[0] + ); + + # We want to know if we're under CPAN early to avoid prompting, but + # if we aren't going to try and install anything anyway then skip the + # check entirely since we don't want to have to load (and configure) + # an old CPAN just for a cosmetic message + + $UnderCPAN = _check_lock(1) unless $SkipInstall; + + while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) { + my ( @required, @tests, @skiptests ); + my $default = 1; + my $conflict = 0; + + if ( $feature =~ m/^-(\w+)$/ ) { + my $option = lc($1); + + # check for a newer version of myself + _update_to( $modules, @_ ) and return if $option eq 'version'; + + # sets CPAN configuration options + $Config = $modules if $option eq 'config'; + + # promote every features to core status + $core_all = ( $modules =~ /^all$/i ) and next + if $option eq 'core'; + + next unless $option eq 'core'; + } + + print "[" . ( $FeatureMap{ lc($feature) } || $feature ) . "]\n"; + + $modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' ); + + unshift @$modules, -default => &{ shift(@$modules) } + if ( ref( $modules->[0] ) eq 'CODE' ); # XXX: bugward combatability + + while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) { + if ( $mod =~ m/^-(\w+)$/ ) { + my $option = lc($1); + + $default = $arg if ( $option eq 'default' ); + $conflict = $arg if ( $option eq 'conflict' ); + @tests = @{$arg} if ( $option eq 'tests' ); + @skiptests = @{$arg} if ( $option eq 'skiptests' ); + + next; + } + + printf( "- %-${maxlen}s ...", $mod ); + + if ( $arg and $arg =~ /^\D/ ) { + unshift @$modules, $arg; + $arg = 0; + } + + # XXX: check for conflicts and uninstalls(!) them. + my $cur = _load($mod); + if (_version_cmp ($cur, $arg) >= 0) + { + print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n"; + push @Existing, $mod => $arg; + $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; + } + else { + if (not defined $cur) # indeed missing + { + print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n"; + } + else + { + # no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above + print "too old. ($cur < $arg)\n"; + } + + push @required, $mod => $arg; + } + } + + next unless @required; + + my $mandatory = ( $feature eq '-core' or $core_all ); + + if ( + !$SkipInstall + and ( + $CheckOnly + or ($mandatory and $UnderCPAN) + or $AllDeps + or _prompt( + qq{==> Auto-install the } + . ( @required / 2 ) + . ( $mandatory ? ' mandatory' : ' optional' ) + . qq{ module(s) from CPAN?}, + $default ? 'y' : 'n', + ) =~ /^[Yy]/ + ) + ) + { + push( @Missing, @required ); + $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; + } + + elsif ( !$SkipInstall + and $default + and $mandatory + and + _prompt( qq{==> The module(s) are mandatory! Really skip?}, 'n', ) + =~ /^[Nn]/ ) + { + push( @Missing, @required ); + $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; + } + + else { + $DisabledTests{$_} = 1 for map { glob($_) } @tests; + } + } + + if ( @Missing and not( $CheckOnly or $UnderCPAN ) ) { + require Config; + print +"*** Dependencies will be installed the next time you type '$Config::Config{make}'.\n"; + + # make an educated guess of whether we'll need root permission. + print " (You may need to do that as the 'root' user.)\n" + if eval '$>'; + } + print "*** $class configuration finished.\n"; + + chdir $cwd; + + # import to main:: + no strict 'refs'; + *{'main::WriteMakefile'} = \&Write if caller(0) eq 'main'; + + return (@Existing, @Missing); +} + +sub _running_under { + my $thing = shift; + print <<"END_MESSAGE"; +*** Since we're running under ${thing}, I'll just let it take care + of the dependency's installation later. +END_MESSAGE + return 1; +} + +# Check to see if we are currently running under CPAN.pm and/or CPANPLUS; +# if we are, then we simply let it taking care of our dependencies +sub _check_lock { + return unless @Missing or @_; + + my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING}; + + if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) { + return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS'); + } + + require CPAN; + + if ($CPAN::VERSION > '1.89') { + if ($cpan_env) { + return _running_under('CPAN'); + } + return; # CPAN.pm new enough, don't need to check further + } + + # last ditch attempt, this -will- configure CPAN, very sorry + + _load_cpan(1); # force initialize even though it's already loaded + + # Find the CPAN lock-file + my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" ); + return unless -f $lock; + + # Check the lock + local *LOCK; + return unless open(LOCK, $lock); + + if ( + ( $^O eq 'MSWin32' ? _under_cpan() : == getppid() ) + and ( $CPAN::Config->{prerequisites_policy} || '' ) ne 'ignore' + ) { + print <<'END_MESSAGE'; + +*** Since we're running under CPAN, I'll just let it take care + of the dependency's installation later. +END_MESSAGE + return 1; + } + + close LOCK; + return; +} + +sub install { + my $class = shift; + + my $i; # used below to strip leading '-' from config keys + my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } ); + + my ( @modules, @installed ); + while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) { + + # grep out those already installed + if ( _version_cmp( _load($pkg), $ver ) >= 0 ) { + push @installed, $pkg; + } + else { + push @modules, $pkg, $ver; + } + } + + return @installed unless @modules; # nothing to do + return @installed if _check_lock(); # defer to the CPAN shell + + print "*** Installing dependencies...\n"; + + return unless _connected_to('cpan.org'); + + my %args = @config; + my %failed; + local *FAILED; + if ( $args{do_once} and open( FAILED, '.#autoinstall.failed' ) ) { + while () { chomp; $failed{$_}++ } + close FAILED; + + my @newmod; + while ( my ( $k, $v ) = splice( @modules, 0, 2 ) ) { + push @newmod, ( $k => $v ) unless $failed{$k}; + } + @modules = @newmod; + } + + if ( _has_cpanplus() and not $ENV{PERL_AUTOINSTALL_PREFER_CPAN} ) { + _install_cpanplus( \@modules, \@config ); + } else { + _install_cpan( \@modules, \@config ); + } + + print "*** $class installation finished.\n"; + + # see if we have successfully installed them + while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { + if ( _version_cmp( _load($pkg), $ver ) >= 0 ) { + push @installed, $pkg; + } + elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) { + print FAILED "$pkg\n"; + } + } + + close FAILED if $args{do_once}; + + return @installed; +} + +sub _install_cpanplus { + my @modules = @{ +shift }; + my @config = _cpanplus_config( @{ +shift } ); + my $installed = 0; + + require CPANPLUS::Backend; + my $cp = CPANPLUS::Backend->new; + my $conf = $cp->configure_object; + + return unless $conf->can('conf') # 0.05x+ with "sudo" support + or _can_write($conf->_get_build('base')); # 0.04x + + # if we're root, set UNINST=1 to avoid trouble unless user asked for it. + my $makeflags = $conf->get_conf('makeflags') || ''; + if ( UNIVERSAL::isa( $makeflags, 'HASH' ) ) { + # 0.03+ uses a hashref here + $makeflags->{UNINST} = 1 unless exists $makeflags->{UNINST}; + + } else { + # 0.02 and below uses a scalar + $makeflags = join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) + if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); + + } + $conf->set_conf( makeflags => $makeflags ); + $conf->set_conf( prereqs => 1 ); + + + + while ( my ( $key, $val ) = splice( @config, 0, 2 ) ) { + $conf->set_conf( $key, $val ); + } + + my $modtree = $cp->module_tree; + while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { + print "*** Installing $pkg...\n"; + + MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; + + my $success; + my $obj = $modtree->{$pkg}; + + if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) { + my $pathname = $pkg; + $pathname =~ s/::/\\W/; + + foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { + delete $INC{$inc}; + } + + my $rv = $cp->install( modules => [ $obj->{module} ] ); + + if ( $rv and ( $rv->{ $obj->{module} } or $rv->{ok} ) ) { + print "*** $pkg successfully installed.\n"; + $success = 1; + } else { + print "*** $pkg installation cancelled.\n"; + $success = 0; + } + + $installed += $success; + } else { + print << "."; +*** Could not find a version $ver or above for $pkg; skipping. +. + } + + MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; + } + + return $installed; +} + +sub _cpanplus_config { + my @config = (); + while ( @_ ) { + my ($key, $value) = (shift(), shift()); + if ( $key eq 'prerequisites_policy' ) { + if ( $value eq 'follow' ) { + $value = CPANPLUS::Internals::Constants::PREREQ_INSTALL(); + } elsif ( $value eq 'ask' ) { + $value = CPANPLUS::Internals::Constants::PREREQ_ASK(); + } elsif ( $value eq 'ignore' ) { + $value = CPANPLUS::Internals::Constants::PREREQ_IGNORE(); + } else { + die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n"; + } + } else { + die "*** Cannot convert option $key to CPANPLUS version.\n"; + } + } + return @config; +} + +sub _install_cpan { + my @modules = @{ +shift }; + my @config = @{ +shift }; + my $installed = 0; + my %args; + + _load_cpan(); + require Config; + + if (CPAN->VERSION < 1.80) { + # no "sudo" support, probe for writableness + return unless _can_write( MM->catfile( $CPAN::Config->{cpan_home}, 'sources' ) ) + and _can_write( $Config::Config{sitelib} ); + } + + # if we're root, set UNINST=1 to avoid trouble unless user asked for it. + my $makeflags = $CPAN::Config->{make_install_arg} || ''; + $CPAN::Config->{make_install_arg} = + join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) + if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); + + # don't show start-up info + $CPAN::Config->{inhibit_startup_message} = 1; + + # set additional options + while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) { + ( $args{$opt} = $arg, next ) + if $opt =~ /^force$/; # pseudo-option + $CPAN::Config->{$opt} = $arg; + } + + local $CPAN::Config->{prerequisites_policy} = 'follow'; + + while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { + MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; + + print "*** Installing $pkg...\n"; + + my $obj = CPAN::Shell->expand( Module => $pkg ); + my $success = 0; + + if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) { + my $pathname = $pkg; + $pathname =~ s/::/\\W/; + + foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { + delete $INC{$inc}; + } + + my $rv = $args{force} ? CPAN::Shell->force( install => $pkg ) + : CPAN::Shell->install($pkg); + $rv ||= eval { + $CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, ) + ->{install} + if $CPAN::META; + }; + + if ( $rv eq 'YES' ) { + print "*** $pkg successfully installed.\n"; + $success = 1; + } + else { + print "*** $pkg installation failed.\n"; + $success = 0; + } + + $installed += $success; + } + else { + print << "."; +*** Could not find a version $ver or above for $pkg; skipping. +. + } + + MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; + } + + return $installed; +} + +sub _has_cpanplus { + return ( + $HasCPANPLUS = ( + $INC{'CPANPLUS/Config.pm'} + or _load('CPANPLUS::Shell::Default') + ) + ); +} + +# make guesses on whether we're under the CPAN installation directory +sub _under_cpan { + require Cwd; + require File::Spec; + + my $cwd = File::Spec->canonpath( Cwd::cwd() ); + my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} ); + + return ( index( $cwd, $cpan ) > -1 ); +} + +sub _update_to { + my $class = __PACKAGE__; + my $ver = shift; + + return + if _version_cmp( _load($class), $ver ) >= 0; # no need to upgrade + + if ( + _prompt( "==> A newer version of $class ($ver) is required. Install?", + 'y' ) =~ /^[Nn]/ + ) + { + die "*** Please install $class $ver manually.\n"; + } + + print << "."; +*** Trying to fetch it from CPAN... +. + + # install ourselves + _load($class) and return $class->import(@_) + if $class->install( [], $class, $ver ); + + print << '.'; exit 1; + +*** Cannot bootstrap myself. :-( Installation terminated. +. +} + +# check if we're connected to some host, using inet_aton +sub _connected_to { + my $site = shift; + + return ( + ( _load('Socket') and Socket::inet_aton($site) ) or _prompt( + qq( +*** Your host cannot resolve the domain name '$site', which + probably means the Internet connections are unavailable. +==> Should we try to install the required module(s) anyway?), 'n' + ) =~ /^[Yy]/ + ); +} + +# check if a directory is writable; may create it on demand +sub _can_write { + my $path = shift; + mkdir( $path, 0755 ) unless -e $path; + + return 1 if -w $path; + + print << "."; +*** You are not allowed to write to the directory '$path'; + the installation may fail due to insufficient permissions. +. + + if ( + eval '$>' and lc(`sudo -V`) =~ /version/ and _prompt( + qq( +==> Should we try to re-execute the autoinstall process with 'sudo'?), + ((-t STDIN) ? 'y' : 'n') + ) =~ /^[Yy]/ + ) + { + + # try to bootstrap ourselves from sudo + print << "."; +*** Trying to re-execute the autoinstall process with 'sudo'... +. + my $missing = join( ',', @Missing ); + my $config = join( ',', + UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) + if $Config; + + return + unless system( 'sudo', $^X, $0, "--config=$config", + "--installdeps=$missing" ); + + print << "."; +*** The 'sudo' command exited with error! Resuming... +. + } + + return _prompt( + qq( +==> Should we try to install the required module(s) anyway?), 'n' + ) =~ /^[Yy]/; +} + +# load a module and return the version it reports +sub _load { + my $mod = pop; # class/instance doesn't matter + my $file = $mod; + + $file =~ s|::|/|g; + $file .= '.pm'; + + local $@; + return eval { require $file; $mod->VERSION } || ( $@ ? undef: 0 ); +} + +# Load CPAN.pm and it's configuration +sub _load_cpan { + return if $CPAN::VERSION and $CPAN::Config and not @_; + require CPAN; + + # CPAN-1.82+ adds CPAN::Config::AUTOLOAD to redirect to + # CPAN::HandleConfig->load. CPAN reports that the redirection + # is deprecated in a warning printed at the user. + + # CPAN-1.81 expects CPAN::HandleConfig->load, does not have + # $CPAN::HandleConfig::VERSION but cannot handle + # CPAN::Config->load + + # Which "versions expect CPAN::Config->load? + + if ( $CPAN::HandleConfig::VERSION + || CPAN::HandleConfig->can('load') + ) { + # Newer versions of CPAN have a HandleConfig module + CPAN::HandleConfig->load; + } else { + # Older versions had the load method in Config directly + CPAN::Config->load; + } +} + +# compare two versions, either use Sort::Versions or plain comparison +# return values same as <=> +sub _version_cmp { + my ( $cur, $min ) = @_; + return -1 unless defined $cur; # if 0 keep comparing + return 1 unless $min; + + $cur =~ s/\s+$//; + + # check for version numbers that are not in decimal format + if ( ref($cur) or ref($min) or $cur =~ /v|\..*\./ or $min =~ /v|\..*\./ ) { + if ( ( $version::VERSION or defined( _load('version') )) and + version->can('new') + ) { + + # use version.pm if it is installed. + return version->new($cur) <=> version->new($min); + } + elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) ) + { + + # use Sort::Versions as the sorting algorithm for a.b.c versions + return Sort::Versions::versioncmp( $cur, $min ); + } + + warn "Cannot reliably compare non-decimal formatted versions.\n" + . "Please install version.pm or Sort::Versions.\n"; + } + + # plain comparison + local $^W = 0; # shuts off 'not numeric' bugs + return $cur <=> $min; +} + +# nothing; this usage is deprecated. +sub main::PREREQ_PM { return {}; } + +sub _make_args { + my %args = @_; + + $args{PREREQ_PM} = { %{ $args{PREREQ_PM} || {} }, @Existing, @Missing } + if $UnderCPAN or $TestOnly; + + if ( $args{EXE_FILES} and -e 'MANIFEST' ) { + require ExtUtils::Manifest; + my $manifest = ExtUtils::Manifest::maniread('MANIFEST'); + + $args{EXE_FILES} = + [ grep { exists $manifest->{$_} } @{ $args{EXE_FILES} } ]; + } + + $args{test}{TESTS} ||= 't/*.t'; + $args{test}{TESTS} = join( ' ', + grep { !exists( $DisabledTests{$_} ) } + map { glob($_) } split( /\s+/, $args{test}{TESTS} ) ); + + my $missing = join( ',', @Missing ); + my $config = + join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) + if $Config; + + $PostambleActions = ( + ($missing and not $UnderCPAN) + ? "\$(PERL) $0 --config=$config --installdeps=$missing" + : "\$(NOECHO) \$(NOOP)" + ); + + return %args; +} + +# a wrapper to ExtUtils::MakeMaker::WriteMakefile +sub Write { + require Carp; + Carp::croak "WriteMakefile: Need even number of args" if @_ % 2; + + if ($CheckOnly) { + print << "."; +*** Makefile not written in check-only mode. +. + return; + } + + my %args = _make_args(@_); + + no strict 'refs'; + + $PostambleUsed = 0; + local *MY::postamble = \&postamble unless defined &MY::postamble; + ExtUtils::MakeMaker::WriteMakefile(%args); + + print << "." unless $PostambleUsed; +*** WARNING: Makefile written with customized MY::postamble() without + including contents from Module::AutoInstall::postamble() -- + auto installation features disabled. Please contact the author. +. + + return 1; +} + +sub postamble { + $PostambleUsed = 1; + + return <<"END_MAKE"; + +config :: installdeps +\t\$(NOECHO) \$(NOOP) + +checkdeps :: +\t\$(PERL) $0 --checkdeps + +installdeps :: +\t$PostambleActions + +END_MAKE + +} + +1; + +__END__ + +#line 1071 diff --git a/api/perl/inc/Module/Install.pm b/api/perl/inc/Module/Install.pm new file mode 100644 index 0000000..8ee839d --- /dev/null +++ b/api/perl/inc/Module/Install.pm @@ -0,0 +1,470 @@ +#line 1 +package Module::Install; + +# For any maintainers: +# The load order for Module::Install is a bit magic. +# It goes something like this... +# +# IF ( host has Module::Install installed, creating author mode ) { +# 1. Makefile.PL calls "use inc::Module::Install" +# 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install +# 3. The installed version of inc::Module::Install loads +# 4. inc::Module::Install calls "require Module::Install" +# 5. The ./inc/ version of Module::Install loads +# } ELSE { +# 1. Makefile.PL calls "use inc::Module::Install" +# 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install +# 3. The ./inc/ version of Module::Install loads +# } + +use 5.005; +use strict 'vars'; +use Cwd (); +use File::Find (); +use File::Path (); + +use vars qw{$VERSION $MAIN}; +BEGIN { + # All Module::Install core packages now require synchronised versions. + # This will be used to ensure we don't accidentally load old or + # different versions of modules. + # This is not enforced yet, but will be some time in the next few + # releases once we can make sure it won't clash with custom + # Module::Install extensions. + $VERSION = '1.00'; + + # Storage for the pseudo-singleton + $MAIN = undef; + + *inc::Module::Install::VERSION = *VERSION; + @inc::Module::Install::ISA = __PACKAGE__; + +} + +sub import { + my $class = shift; + my $self = $class->new(@_); + my $who = $self->_caller; + + #------------------------------------------------------------- + # all of the following checks should be included in import(), + # to allow "eval 'require Module::Install; 1' to test + # installation of Module::Install. (RT #51267) + #------------------------------------------------------------- + + # Whether or not inc::Module::Install is actually loaded, the + # $INC{inc/Module/Install.pm} is what will still get set as long as + # the caller loaded module this in the documented manner. + # If not set, the caller may NOT have loaded the bundled version, and thus + # they may not have a MI version that works with the Makefile.PL. This would + # result in false errors or unexpected behaviour. And we don't want that. + my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; + unless ( $INC{$file} ) { die <<"END_DIE" } + +Please invoke ${\__PACKAGE__} with: + + use inc::${\__PACKAGE__}; + +not: + + use ${\__PACKAGE__}; + +END_DIE + + # This reportedly fixes a rare Win32 UTC file time issue, but + # as this is a non-cross-platform XS module not in the core, + # we shouldn't really depend on it. See RT #24194 for detail. + # (Also, this module only supports Perl 5.6 and above). + eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; + + # If the script that is loading Module::Install is from the future, + # then make will detect this and cause it to re-run over and over + # again. This is bad. Rather than taking action to touch it (which + # is unreliable on some platforms and requires write permissions) + # for now we should catch this and refuse to run. + if ( -f $0 ) { + my $s = (stat($0))[9]; + + # If the modification time is only slightly in the future, + # sleep briefly to remove the problem. + my $a = $s - time; + if ( $a > 0 and $a < 5 ) { sleep 5 } + + # Too far in the future, throw an error. + my $t = time; + if ( $s > $t ) { die <<"END_DIE" } + +Your installer $0 has a modification time in the future ($s > $t). + +This is known to create infinite loops in make. + +Please correct this, then run $0 again. + +END_DIE + } + + + # Build.PL was formerly supported, but no longer is due to excessive + # difficulty in implementing every single feature twice. + if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } + +Module::Install no longer supports Build.PL. + +It was impossible to maintain duel backends, and has been deprecated. + +Please remove all Build.PL files and only use the Makefile.PL installer. + +END_DIE + + #------------------------------------------------------------- + + # To save some more typing in Module::Install installers, every... + # use inc::Module::Install + # ...also acts as an implicit use strict. + $^H |= strict::bits(qw(refs subs vars)); + + #------------------------------------------------------------- + + unless ( -f $self->{file} ) { + foreach my $key (keys %INC) { + delete $INC{$key} if $key =~ /Module\/Install/; + } + + local $^W; + require "$self->{path}/$self->{dispatch}.pm"; + File::Path::mkpath("$self->{prefix}/$self->{author}"); + $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); + $self->{admin}->init; + @_ = ($class, _self => $self); + goto &{"$self->{name}::import"}; + } + + local $^W; + *{"${who}::AUTOLOAD"} = $self->autoload; + $self->preload; + + # Unregister loader and worker packages so subdirs can use them again + delete $INC{'inc/Module/Install.pm'}; + delete $INC{'Module/Install.pm'}; + + # Save to the singleton + $MAIN = $self; + + return 1; +} + +sub autoload { + my $self = shift; + my $who = $self->_caller; + my $cwd = Cwd::cwd(); + my $sym = "${who}::AUTOLOAD"; + $sym->{$cwd} = sub { + my $pwd = Cwd::cwd(); + if ( my $code = $sym->{$pwd} ) { + # Delegate back to parent dirs + goto &$code unless $cwd eq $pwd; + } + unless ($$sym =~ s/([^:]+)$//) { + # XXX: it looks like we can't retrieve the missing function + # via $$sym (usually $main::AUTOLOAD) in this case. + # I'm still wondering if we should slurp Makefile.PL to + # get some context or not ... + my ($package, $file, $line) = caller; + die <<"EOT"; +Unknown function is found at $file line $line. +Execution of $file aborted due to runtime errors. + +If you're a contributor to a project, you may need to install +some Module::Install extensions from CPAN (or other repository). +If you're a user of a module, please contact the author. +EOT + } + my $method = $1; + if ( uc($method) eq $method ) { + # Do nothing + return; + } elsif ( $method =~ /^_/ and $self->can($method) ) { + # Dispatch to the root M:I class + return $self->$method(@_); + } + + # Dispatch to the appropriate plugin + unshift @_, ( $self, $1 ); + goto &{$self->can('call')}; + }; +} + +sub preload { + my $self = shift; + unless ( $self->{extensions} ) { + $self->load_extensions( + "$self->{prefix}/$self->{path}", $self + ); + } + + my @exts = @{$self->{extensions}}; + unless ( @exts ) { + @exts = $self->{admin}->load_all_extensions; + } + + my %seen; + foreach my $obj ( @exts ) { + while (my ($method, $glob) = each %{ref($obj) . '::'}) { + next unless $obj->can($method); + next if $method =~ /^_/; + next if $method eq uc($method); + $seen{$method}++; + } + } + + my $who = $self->_caller; + foreach my $name ( sort keys %seen ) { + local $^W; + *{"${who}::$name"} = sub { + ${"${who}::AUTOLOAD"} = "${who}::$name"; + goto &{"${who}::AUTOLOAD"}; + }; + } +} + +sub new { + my ($class, %args) = @_; + + delete $INC{'FindBin.pm'}; + { + # to suppress the redefine warning + local $SIG{__WARN__} = sub {}; + require FindBin; + } + + # ignore the prefix on extension modules built from top level. + my $base_path = Cwd::abs_path($FindBin::Bin); + unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) { + delete $args{prefix}; + } + return $args{_self} if $args{_self}; + + $args{dispatch} ||= 'Admin'; + $args{prefix} ||= 'inc'; + $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); + $args{bundle} ||= 'inc/BUNDLES'; + $args{base} ||= $base_path; + $class =~ s/^\Q$args{prefix}\E:://; + $args{name} ||= $class; + $args{version} ||= $class->VERSION; + unless ( $args{path} ) { + $args{path} = $args{name}; + $args{path} =~ s!::!/!g; + } + $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; + $args{wrote} = 0; + + bless( \%args, $class ); +} + +sub call { + my ($self, $method) = @_; + my $obj = $self->load($method) or return; + splice(@_, 0, 2, $obj); + goto &{$obj->can($method)}; +} + +sub load { + my ($self, $method) = @_; + + $self->load_extensions( + "$self->{prefix}/$self->{path}", $self + ) unless $self->{extensions}; + + foreach my $obj (@{$self->{extensions}}) { + return $obj if $obj->can($method); + } + + my $admin = $self->{admin} or die <<"END_DIE"; +The '$method' method does not exist in the '$self->{prefix}' path! +Please remove the '$self->{prefix}' directory and run $0 again to load it. +END_DIE + + my $obj = $admin->load($method, 1); + push @{$self->{extensions}}, $obj; + + $obj; +} + +sub load_extensions { + my ($self, $path, $top) = @_; + + my $should_reload = 0; + unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { + unshift @INC, $self->{prefix}; + $should_reload = 1; + } + + foreach my $rv ( $self->find_extensions($path) ) { + my ($file, $pkg) = @{$rv}; + next if $self->{pathnames}{$pkg}; + + local $@; + my $new = eval { local $^W; require $file; $pkg->can('new') }; + unless ( $new ) { + warn $@ if $@; + next; + } + $self->{pathnames}{$pkg} = + $should_reload ? delete $INC{$file} : $INC{$file}; + push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); + } + + $self->{extensions} ||= []; +} + +sub find_extensions { + my ($self, $path) = @_; + + my @found; + File::Find::find( sub { + my $file = $File::Find::name; + return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; + my $subpath = $1; + return if lc($subpath) eq lc($self->{dispatch}); + + $file = "$self->{path}/$subpath.pm"; + my $pkg = "$self->{name}::$subpath"; + $pkg =~ s!/!::!g; + + # If we have a mixed-case package name, assume case has been preserved + # correctly. Otherwise, root through the file to locate the case-preserved + # version of the package name. + if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { + my $content = Module::Install::_read($subpath . '.pm'); + my $in_pod = 0; + foreach ( split //, $content ) { + $in_pod = 1 if /^=\w/; + $in_pod = 0 if /^=cut/; + next if ($in_pod || /^=cut/); # skip pod text + next if /^\s*#/; # and comments + if ( m/^\s*package\s+($pkg)\s*;/i ) { + $pkg = $1; + last; + } + } + } + + push @found, [ $file, $pkg ]; + }, $path ) if -d $path; + + @found; +} + + + + + +##################################################################### +# Common Utility Functions + +sub _caller { + my $depth = 0; + my $call = caller($depth); + while ( $call eq __PACKAGE__ ) { + $depth++; + $call = caller($depth); + } + return $call; +} + +# Done in evals to avoid confusing Perl::MinimumVersion +eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; +sub _read { + local *FH; + open( FH, '<', $_[0] ) or die "open($_[0]): $!"; + my $string = do { local $/; }; + close FH or die "close($_[0]): $!"; + return $string; +} +END_NEW +sub _read { + local *FH; + open( FH, "< $_[0]" ) or die "open($_[0]): $!"; + my $string = do { local $/; }; + close FH or die "close($_[0]): $!"; + return $string; +} +END_OLD + +sub _readperl { + my $string = Module::Install::_read($_[0]); + $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; + $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; + $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; + return $string; +} + +sub _readpod { + my $string = Module::Install::_read($_[0]); + $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; + return $string if $_[0] =~ /\.pod\z/; + $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; + $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; + $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; + $string =~ s/^\n+//s; + return $string; +} + +# Done in evals to avoid confusing Perl::MinimumVersion +eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; +sub _write { + local *FH; + open( FH, '>', $_[0] ) or die "open($_[0]): $!"; + foreach ( 1 .. $#_ ) { + print FH $_[$_] or die "print($_[0]): $!"; + } + close FH or die "close($_[0]): $!"; +} +END_NEW +sub _write { + local *FH; + open( FH, "> $_[0]" ) or die "open($_[0]): $!"; + foreach ( 1 .. $#_ ) { + print FH $_[$_] or die "print($_[0]): $!"; + } + close FH or die "close($_[0]): $!"; +} +END_OLD + +# _version is for processing module versions (eg, 1.03_05) not +# Perl versions (eg, 5.8.1). +sub _version ($) { + my $s = shift || 0; + my $d =()= $s =~ /(\.)/g; + if ( $d >= 2 ) { + # Normalise multipart versions + $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; + } + $s =~ s/^(\d+)\.?//; + my $l = $1 || 0; + my @v = map { + $_ . '0' x (3 - length $_) + } $s =~ /(\d{1,3})\D?/g; + $l = $l . '.' . join '', @v if @v; + return $l + 0; +} + +sub _cmp ($$) { + _version($_[0]) <=> _version($_[1]); +} + +# Cloned from Params::Util::_CLASS +sub _CLASS ($) { + ( + defined $_[0] + and + ! ref $_[0] + and + $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s + ) ? $_[0] : undef; +} + +1; + +# Copyright 2008 - 2010 Adam Kennedy. diff --git a/api/perl/inc/Module/Install/AutoInstall.pm b/api/perl/inc/Module/Install/AutoInstall.pm new file mode 100644 index 0000000..f1f5356 --- /dev/null +++ b/api/perl/inc/Module/Install/AutoInstall.pm @@ -0,0 +1,82 @@ +#line 1 +package Module::Install::AutoInstall; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +sub AutoInstall { $_[0] } + +sub run { + my $self = shift; + $self->auto_install_now(@_); +} + +sub write { + my $self = shift; + $self->auto_install(@_); +} + +sub auto_install { + my $self = shift; + return if $self->{done}++; + + # Flatten array of arrays into a single array + my @core = map @$_, map @$_, grep ref, + $self->build_requires, $self->requires; + + my @config = @_; + + # We'll need Module::AutoInstall + $self->include('Module::AutoInstall'); + require Module::AutoInstall; + + my @features_require = Module::AutoInstall->import( + (@config ? (-config => \@config) : ()), + (@core ? (-core => \@core) : ()), + $self->features, + ); + + my %seen; + my @requires = map @$_, map @$_, grep ref, $self->requires; + while (my ($mod, $ver) = splice(@requires, 0, 2)) { + $seen{$mod}{$ver}++; + } + my @build_requires = map @$_, map @$_, grep ref, $self->build_requires; + while (my ($mod, $ver) = splice(@build_requires, 0, 2)) { + $seen{$mod}{$ver}++; + } + my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires; + while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) { + $seen{$mod}{$ver}++; + } + + my @deduped; + while (my ($mod, $ver) = splice(@features_require, 0, 2)) { + push @deduped, $mod => $ver unless $seen{$mod}{$ver}++; + } + + $self->requires(@deduped); + + $self->makemaker_args( Module::AutoInstall::_make_args() ); + + my $class = ref($self); + $self->postamble( + "# --- $class section:\n" . + Module::AutoInstall::postamble() + ); +} + +sub auto_install_now { + my $self = shift; + $self->auto_install(@_); + Module::AutoInstall::do_install(); +} + +1; diff --git a/api/perl/inc/Module/Install/Base.pm b/api/perl/inc/Module/Install/Base.pm new file mode 100644 index 0000000..b55bda3 --- /dev/null +++ b/api/perl/inc/Module/Install/Base.pm @@ -0,0 +1,83 @@ +#line 1 +package Module::Install::Base; + +use strict 'vars'; +use vars qw{$VERSION}; +BEGIN { + $VERSION = '1.00'; +} + +# Suspend handler for "redefined" warnings +BEGIN { + my $w = $SIG{__WARN__}; + $SIG{__WARN__} = sub { $w }; +} + +#line 42 + +sub new { + my $class = shift; + unless ( defined &{"${class}::call"} ) { + *{"${class}::call"} = sub { shift->_top->call(@_) }; + } + unless ( defined &{"${class}::load"} ) { + *{"${class}::load"} = sub { shift->_top->load(@_) }; + } + bless { @_ }, $class; +} + +#line 61 + +sub AUTOLOAD { + local $@; + my $func = eval { shift->_top->autoload } or return; + goto &$func; +} + +#line 75 + +sub _top { + $_[0]->{_top}; +} + +#line 90 + +sub admin { + $_[0]->_top->{admin} + or + Module::Install::Base::FakeAdmin->new; +} + +#line 106 + +sub is_admin { + ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin'); +} + +sub DESTROY {} + +package Module::Install::Base::FakeAdmin; + +use vars qw{$VERSION}; +BEGIN { + $VERSION = $Module::Install::Base::VERSION; +} + +my $fake; + +sub new { + $fake ||= bless(\@_, $_[0]); +} + +sub AUTOLOAD {} + +sub DESTROY {} + +# Restore warning handler +BEGIN { + $SIG{__WARN__} = $SIG{__WARN__}->(); +} + +1; + +#line 159 diff --git a/api/perl/inc/Module/Install/Can.pm b/api/perl/inc/Module/Install/Can.pm new file mode 100644 index 0000000..71ccc27 --- /dev/null +++ b/api/perl/inc/Module/Install/Can.pm @@ -0,0 +1,81 @@ +#line 1 +package Module::Install::Can; + +use strict; +use Config (); +use File::Spec (); +use ExtUtils::MakeMaker (); +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +# check if we can load some module +### Upgrade this to not have to load the module if possible +sub can_use { + my ($self, $mod, $ver) = @_; + $mod =~ s{::|\\}{/}g; + $mod .= '.pm' unless $mod =~ /\.pm$/i; + + my $pkg = $mod; + $pkg =~ s{/}{::}g; + $pkg =~ s{\.pm$}{}i; + + local $@; + eval { require $mod; $pkg->VERSION($ver || 0); 1 }; +} + +# check if we can run some command +sub can_run { + my ($self, $cmd) = @_; + + my $_cmd = $cmd; + return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); + + for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { + next if $dir eq ''; + my $abs = File::Spec->catfile($dir, $_[1]); + return $abs if (-x $abs or $abs = MM->maybe_command($abs)); + } + + return; +} + +# can we locate a (the) C compiler +sub can_cc { + my $self = shift; + my @chunks = split(/ /, $Config::Config{cc}) or return; + + # $Config{cc} may contain args; try to find out the program part + while (@chunks) { + return $self->can_run("@chunks") || (pop(@chunks), next); + } + + return; +} + +# Fix Cygwin bug on maybe_command(); +if ( $^O eq 'cygwin' ) { + require ExtUtils::MM_Cygwin; + require ExtUtils::MM_Win32; + if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { + *ExtUtils::MM_Cygwin::maybe_command = sub { + my ($self, $file) = @_; + if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { + ExtUtils::MM_Win32->maybe_command($file); + } else { + ExtUtils::MM_Unix->maybe_command($file); + } + } + } +} + +1; + +__END__ + +#line 156 diff --git a/api/perl/inc/Module/Install/Fetch.pm b/api/perl/inc/Module/Install/Fetch.pm new file mode 100644 index 0000000..ec1f106 --- /dev/null +++ b/api/perl/inc/Module/Install/Fetch.pm @@ -0,0 +1,93 @@ +#line 1 +package Module::Install::Fetch; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +sub get_file { + my ($self, %args) = @_; + my ($scheme, $host, $path, $file) = + $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; + + if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { + $args{url} = $args{ftp_url} + or (warn("LWP support unavailable!\n"), return); + ($scheme, $host, $path, $file) = + $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; + } + + $|++; + print "Fetching '$file' from $host... "; + + unless (eval { require Socket; Socket::inet_aton($host) }) { + warn "'$host' resolve failed!\n"; + return; + } + + return unless $scheme eq 'ftp' or $scheme eq 'http'; + + require Cwd; + my $dir = Cwd::getcwd(); + chdir $args{local_dir} or return if exists $args{local_dir}; + + if (eval { require LWP::Simple; 1 }) { + LWP::Simple::mirror($args{url}, $file); + } + elsif (eval { require Net::FTP; 1 }) { eval { + # use Net::FTP to get past firewall + my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); + $ftp->login("anonymous", 'anonymous@example.com'); + $ftp->cwd($path); + $ftp->binary; + $ftp->get($file) or (warn("$!\n"), return); + $ftp->quit; + } } + elsif (my $ftp = $self->can_run('ftp')) { eval { + # no Net::FTP, fallback to ftp.exe + require FileHandle; + my $fh = FileHandle->new; + + local $SIG{CHLD} = 'IGNORE'; + unless ($fh->open("|$ftp -n")) { + warn "Couldn't open ftp: $!\n"; + chdir $dir; return; + } + + my @dialog = split(/\n/, <<"END_FTP"); +open $host +user anonymous anonymous\@example.com +cd $path +binary +get $file $file +quit +END_FTP + foreach (@dialog) { $fh->print("$_\n") } + $fh->close; + } } + else { + warn "No working 'ftp' program available!\n"; + chdir $dir; return; + } + + unless (-f $file) { + warn "Fetching failed: $@\n"; + chdir $dir; return; + } + + return if exists $args{size} and -s $file != $args{size}; + system($args{run}) if exists $args{run}; + unlink($file) if $args{remove}; + + print(((!exists $args{check_for} or -e $args{check_for}) + ? "done!" : "failed! ($!)"), "\n"); + chdir $dir; return !$?; +} + +1; diff --git a/api/perl/inc/Module/Install/Include.pm b/api/perl/inc/Module/Install/Include.pm new file mode 100644 index 0000000..a28cd4c --- /dev/null +++ b/api/perl/inc/Module/Install/Include.pm @@ -0,0 +1,34 @@ +#line 1 +package Module::Install::Include; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +sub include { + shift()->admin->include(@_); +} + +sub include_deps { + shift()->admin->include_deps(@_); +} + +sub auto_include { + shift()->admin->auto_include(@_); +} + +sub auto_include_deps { + shift()->admin->auto_include_deps(@_); +} + +sub auto_include_dependent_dists { + shift()->admin->auto_include_dependent_dists(@_); +} + +1; diff --git a/api/perl/inc/Module/Install/Makefile.pm b/api/perl/inc/Module/Install/Makefile.pm new file mode 100644 index 0000000..5dfd0e9 --- /dev/null +++ b/api/perl/inc/Module/Install/Makefile.pm @@ -0,0 +1,415 @@ +#line 1 +package Module::Install::Makefile; + +use strict 'vars'; +use ExtUtils::MakeMaker (); +use Module::Install::Base (); +use Fcntl qw/:flock :seek/; + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +sub Makefile { $_[0] } + +my %seen = (); + +sub prompt { + shift; + + # Infinite loop protection + my @c = caller(); + if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { + die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; + } + + # In automated testing or non-interactive session, always use defaults + if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { + local $ENV{PERL_MM_USE_DEFAULT} = 1; + goto &ExtUtils::MakeMaker::prompt; + } else { + goto &ExtUtils::MakeMaker::prompt; + } +} + +# Store a cleaned up version of the MakeMaker version, +# since we need to behave differently in a variety of +# ways based on the MM version. +my $makemaker = eval $ExtUtils::MakeMaker::VERSION; + +# If we are passed a param, do a "newer than" comparison. +# Otherwise, just return the MakeMaker version. +sub makemaker { + ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 +} + +# Ripped from ExtUtils::MakeMaker 6.56, and slightly modified +# as we only need to know here whether the attribute is an array +# or a hash or something else (which may or may not be appendable). +my %makemaker_argtype = ( + C => 'ARRAY', + CONFIG => 'ARRAY', +# CONFIGURE => 'CODE', # ignore + DIR => 'ARRAY', + DL_FUNCS => 'HASH', + DL_VARS => 'ARRAY', + EXCLUDE_EXT => 'ARRAY', + EXE_FILES => 'ARRAY', + FUNCLIST => 'ARRAY', + H => 'ARRAY', + IMPORTS => 'HASH', + INCLUDE_EXT => 'ARRAY', + LIBS => 'ARRAY', # ignore '' + MAN1PODS => 'HASH', + MAN3PODS => 'HASH', + META_ADD => 'HASH', + META_MERGE => 'HASH', + PL_FILES => 'HASH', + PM => 'HASH', + PMLIBDIRS => 'ARRAY', + PMLIBPARENTDIRS => 'ARRAY', + PREREQ_PM => 'HASH', + CONFIGURE_REQUIRES => 'HASH', + SKIP => 'ARRAY', + TYPEMAPS => 'ARRAY', + XS => 'HASH', +# VERSION => ['version',''], # ignore +# _KEEP_AFTER_FLUSH => '', + + clean => 'HASH', + depend => 'HASH', + dist => 'HASH', + dynamic_lib=> 'HASH', + linkext => 'HASH', + macro => 'HASH', + postamble => 'HASH', + realclean => 'HASH', + test => 'HASH', + tool_autosplit => 'HASH', + + # special cases where you can use makemaker_append + CCFLAGS => 'APPENDABLE', + DEFINE => 'APPENDABLE', + INC => 'APPENDABLE', + LDDLFLAGS => 'APPENDABLE', + LDFROM => 'APPENDABLE', +); + +sub makemaker_args { + my ($self, %new_args) = @_; + my $args = ( $self->{makemaker_args} ||= {} ); + foreach my $key (keys %new_args) { + if ($makemaker_argtype{$key}) { + if ($makemaker_argtype{$key} eq 'ARRAY') { + $args->{$key} = [] unless defined $args->{$key}; + unless (ref $args->{$key} eq 'ARRAY') { + $args->{$key} = [$args->{$key}] + } + push @{$args->{$key}}, + ref $new_args{$key} eq 'ARRAY' + ? @{$new_args{$key}} + : $new_args{$key}; + } + elsif ($makemaker_argtype{$key} eq 'HASH') { + $args->{$key} = {} unless defined $args->{$key}; + foreach my $skey (keys %{ $new_args{$key} }) { + $args->{$key}{$skey} = $new_args{$key}{$skey}; + } + } + elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { + $self->makemaker_append($key => $new_args{$key}); + } + } + else { + if (defined $args->{$key}) { + warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; + } + $args->{$key} = $new_args{$key}; + } + } + return $args; +} + +# For mm args that take multiple space-seperated args, +# append an argument to the current list. +sub makemaker_append { + my $self = shift; + my $name = shift; + my $args = $self->makemaker_args; + $args->{$name} = defined $args->{$name} + ? join( ' ', $args->{$name}, @_ ) + : join( ' ', @_ ); +} + +sub build_subdirs { + my $self = shift; + my $subdirs = $self->makemaker_args->{DIR} ||= []; + for my $subdir (@_) { + push @$subdirs, $subdir; + } +} + +sub clean_files { + my $self = shift; + my $clean = $self->makemaker_args->{clean} ||= {}; + %$clean = ( + %$clean, + FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), + ); +} + +sub realclean_files { + my $self = shift; + my $realclean = $self->makemaker_args->{realclean} ||= {}; + %$realclean = ( + %$realclean, + FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), + ); +} + +sub libs { + my $self = shift; + my $libs = ref $_[0] ? shift : [ shift ]; + $self->makemaker_args( LIBS => $libs ); +} + +sub inc { + my $self = shift; + $self->makemaker_args( INC => shift ); +} + +sub _wanted_t { +} + +sub tests_recursive { + my $self = shift; + my $dir = shift || 't'; + unless ( -d $dir ) { + die "tests_recursive dir '$dir' does not exist"; + } + my %tests = map { $_ => 1 } split / /, ($self->tests || ''); + require File::Find; + File::Find::find( + sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 }, + $dir + ); + $self->tests( join ' ', sort keys %tests ); +} + +sub write { + my $self = shift; + die "&Makefile->write() takes no arguments\n" if @_; + + # Check the current Perl version + my $perl_version = $self->perl_version; + if ( $perl_version ) { + eval "use $perl_version; 1" + or die "ERROR: perl: Version $] is installed, " + . "but we need version >= $perl_version"; + } + + # Make sure we have a new enough MakeMaker + require ExtUtils::MakeMaker; + + if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { + # MakeMaker can complain about module versions that include + # an underscore, even though its own version may contain one! + # Hence the funny regexp to get rid of it. See RT #35800 + # for details. + my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/; + $self->build_requires( 'ExtUtils::MakeMaker' => $v ); + $self->configure_requires( 'ExtUtils::MakeMaker' => $v ); + } else { + # Allow legacy-compatibility with 5.005 by depending on the + # most recent EU:MM that supported 5.005. + $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 ); + $self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 ); + } + + # Generate the MakeMaker params + my $args = $self->makemaker_args; + $args->{DISTNAME} = $self->name; + $args->{NAME} = $self->module_name || $self->name; + $args->{NAME} =~ s/-/::/g; + $args->{VERSION} = $self->version or die <<'EOT'; +ERROR: Can't determine distribution version. Please specify it +explicitly via 'version' in Makefile.PL, or set a valid $VERSION +in a module, and provide its file path via 'version_from' (or +'all_from' if you prefer) in Makefile.PL. +EOT + + $DB::single = 1; + if ( $self->tests ) { + my @tests = split ' ', $self->tests; + my %seen; + $args->{test} = { + TESTS => (join ' ', grep {!$seen{$_}++} @tests), + }; + } elsif ( $Module::Install::ExtraTests::use_extratests ) { + # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness. + # So, just ignore our xt tests here. + } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { + $args->{test} = { + TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), + }; + } + if ( $] >= 5.005 ) { + $args->{ABSTRACT} = $self->abstract; + $args->{AUTHOR} = join ', ', @{$self->author || []}; + } + if ( $self->makemaker(6.10) ) { + $args->{NO_META} = 1; + #$args->{NO_MYMETA} = 1; + } + if ( $self->makemaker(6.17) and $self->sign ) { + $args->{SIGN} = 1; + } + unless ( $self->is_admin ) { + delete $args->{SIGN}; + } + if ( $self->makemaker(6.31) and $self->license ) { + $args->{LICENSE} = $self->license; + } + + my $prereq = ($args->{PREREQ_PM} ||= {}); + %$prereq = ( %$prereq, + map { @$_ } # flatten [module => version] + map { @$_ } + grep $_, + ($self->requires) + ); + + # Remove any reference to perl, PREREQ_PM doesn't support it + delete $args->{PREREQ_PM}->{perl}; + + # Merge both kinds of requires into BUILD_REQUIRES + my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); + %$build_prereq = ( %$build_prereq, + map { @$_ } # flatten [module => version] + map { @$_ } + grep $_, + ($self->configure_requires, $self->build_requires) + ); + + # Remove any reference to perl, BUILD_REQUIRES doesn't support it + delete $args->{BUILD_REQUIRES}->{perl}; + + # Delete bundled dists from prereq_pm, add it to Makefile DIR + my $subdirs = ($args->{DIR} || []); + if ($self->bundles) { + my %processed; + foreach my $bundle (@{ $self->bundles }) { + my ($mod_name, $dist_dir) = @$bundle; + delete $prereq->{$mod_name}; + $dist_dir = File::Basename::basename($dist_dir); # dir for building this module + if (not exists $processed{$dist_dir}) { + if (-d $dist_dir) { + # List as sub-directory to be processed by make + push @$subdirs, $dist_dir; + } + # Else do nothing: the module is already present on the system + $processed{$dist_dir} = undef; + } + } + } + + unless ( $self->makemaker('6.55_03') ) { + %$prereq = (%$prereq,%$build_prereq); + delete $args->{BUILD_REQUIRES}; + } + + if ( my $perl_version = $self->perl_version ) { + eval "use $perl_version; 1" + or die "ERROR: perl: Version $] is installed, " + . "but we need version >= $perl_version"; + + if ( $self->makemaker(6.48) ) { + $args->{MIN_PERL_VERSION} = $perl_version; + } + } + + if ($self->installdirs) { + warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; + $args->{INSTALLDIRS} = $self->installdirs; + } + + my %args = map { + ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) + } keys %$args; + + my $user_preop = delete $args{dist}->{PREOP}; + if ( my $preop = $self->admin->preop($user_preop) ) { + foreach my $key ( keys %$preop ) { + $args{dist}->{$key} = $preop->{$key}; + } + } + + my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); + $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); +} + +sub fix_up_makefile { + my $self = shift; + my $makefile_name = shift; + my $top_class = ref($self->_top) || ''; + my $top_version = $self->_top->VERSION || ''; + + my $preamble = $self->preamble + ? "# Preamble by $top_class $top_version\n" + . $self->preamble + : ''; + my $postamble = "# Postamble by $top_class $top_version\n" + . ($self->postamble || ''); + + local *MAKEFILE; + open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; + eval { flock MAKEFILE, LOCK_EX }; + my $makefile = do { local $/; }; + + $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; + $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; + $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; + $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; + $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; + + # Module::Install will never be used to build the Core Perl + # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks + # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist + $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; + #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; + + # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. + $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; + + # XXX - This is currently unused; not sure if it breaks other MM-users + # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; + + seek MAKEFILE, 0, SEEK_SET; + truncate MAKEFILE, 0; + print MAKEFILE "$preamble$makefile$postamble" or die $!; + close MAKEFILE or die $!; + + 1; +} + +sub preamble { + my ($self, $text) = @_; + $self->{preamble} = $text . $self->{preamble} if defined $text; + $self->{preamble}; +} + +sub postamble { + my ($self, $text) = @_; + $self->{postamble} ||= $self->admin->postamble; + $self->{postamble} .= $text if defined $text; + $self->{postamble} +} + +1; + +__END__ + +#line 541 diff --git a/api/perl/inc/Module/Install/Metadata.pm b/api/perl/inc/Module/Install/Metadata.pm new file mode 100644 index 0000000..cfe45b3 --- /dev/null +++ b/api/perl/inc/Module/Install/Metadata.pm @@ -0,0 +1,715 @@ +#line 1 +package Module::Install::Metadata; + +use strict 'vars'; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +my @boolean_keys = qw{ + sign +}; + +my @scalar_keys = qw{ + name + module_name + abstract + version + distribution_type + tests + installdirs +}; + +my @tuple_keys = qw{ + configure_requires + build_requires + requires + recommends + bundles + resources +}; + +my @resource_keys = qw{ + homepage + bugtracker + repository +}; + +my @array_keys = qw{ + keywords + author +}; + +*authors = \&author; + +sub Meta { shift } +sub Meta_BooleanKeys { @boolean_keys } +sub Meta_ScalarKeys { @scalar_keys } +sub Meta_TupleKeys { @tuple_keys } +sub Meta_ResourceKeys { @resource_keys } +sub Meta_ArrayKeys { @array_keys } + +foreach my $key ( @boolean_keys ) { + *$key = sub { + my $self = shift; + if ( defined wantarray and not @_ ) { + return $self->{values}->{$key}; + } + $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); + return $self; + }; +} + +foreach my $key ( @scalar_keys ) { + *$key = sub { + my $self = shift; + return $self->{values}->{$key} if defined wantarray and !@_; + $self->{values}->{$key} = shift; + return $self; + }; +} + +foreach my $key ( @array_keys ) { + *$key = sub { + my $self = shift; + return $self->{values}->{$key} if defined wantarray and !@_; + $self->{values}->{$key} ||= []; + push @{$self->{values}->{$key}}, @_; + return $self; + }; +} + +foreach my $key ( @resource_keys ) { + *$key = sub { + my $self = shift; + unless ( @_ ) { + return () unless $self->{values}->{resources}; + return map { $_->[1] } + grep { $_->[0] eq $key } + @{ $self->{values}->{resources} }; + } + return $self->{values}->{resources}->{$key} unless @_; + my $uri = shift or die( + "Did not provide a value to $key()" + ); + $self->resources( $key => $uri ); + return 1; + }; +} + +foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { + *$key = sub { + my $self = shift; + return $self->{values}->{$key} unless @_; + my @added; + while ( @_ ) { + my $module = shift or last; + my $version = shift || 0; + push @added, [ $module, $version ]; + } + push @{ $self->{values}->{$key} }, @added; + return map {@$_} @added; + }; +} + +# Resource handling +my %lc_resource = map { $_ => 1 } qw{ + homepage + license + bugtracker + repository +}; + +sub resources { + my $self = shift; + while ( @_ ) { + my $name = shift or last; + my $value = shift or next; + if ( $name eq lc $name and ! $lc_resource{$name} ) { + die("Unsupported reserved lowercase resource '$name'"); + } + $self->{values}->{resources} ||= []; + push @{ $self->{values}->{resources} }, [ $name, $value ]; + } + $self->{values}->{resources}; +} + +# Aliases for build_requires that will have alternative +# meanings in some future version of META.yml. +sub test_requires { shift->build_requires(@_) } +sub install_requires { shift->build_requires(@_) } + +# Aliases for installdirs options +sub install_as_core { $_[0]->installdirs('perl') } +sub install_as_cpan { $_[0]->installdirs('site') } +sub install_as_site { $_[0]->installdirs('site') } +sub install_as_vendor { $_[0]->installdirs('vendor') } + +sub dynamic_config { + my $self = shift; + unless ( @_ ) { + warn "You MUST provide an explicit true/false value to dynamic_config\n"; + return $self; + } + $self->{values}->{dynamic_config} = $_[0] ? 1 : 0; + return 1; +} + +sub perl_version { + my $self = shift; + return $self->{values}->{perl_version} unless @_; + my $version = shift or die( + "Did not provide a value to perl_version()" + ); + + # Normalize the version + $version = $self->_perl_version($version); + + # We don't support the reall old versions + unless ( $version >= 5.005 ) { + die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; + } + + $self->{values}->{perl_version} = $version; +} + +sub all_from { + my ( $self, $file ) = @_; + + unless ( defined($file) ) { + my $name = $self->name or die( + "all_from called with no args without setting name() first" + ); + $file = join('/', 'lib', split(/-/, $name)) . '.pm'; + $file =~ s{.*/}{} unless -e $file; + unless ( -e $file ) { + die("all_from cannot find $file from $name"); + } + } + unless ( -f $file ) { + die("The path '$file' does not exist, or is not a file"); + } + + $self->{values}{all_from} = $file; + + # Some methods pull from POD instead of code. + # If there is a matching .pod, use that instead + my $pod = $file; + $pod =~ s/\.pm$/.pod/i; + $pod = $file unless -e $pod; + + # Pull the different values + $self->name_from($file) unless $self->name; + $self->version_from($file) unless $self->version; + $self->perl_version_from($file) unless $self->perl_version; + $self->author_from($pod) unless @{$self->author || []}; + $self->license_from($pod) unless $self->license; + $self->abstract_from($pod) unless $self->abstract; + + return 1; +} + +sub provides { + my $self = shift; + my $provides = ( $self->{values}->{provides} ||= {} ); + %$provides = (%$provides, @_) if @_; + return $provides; +} + +sub auto_provides { + my $self = shift; + return $self unless $self->is_admin; + unless (-e 'MANIFEST') { + warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; + return $self; + } + # Avoid spurious warnings as we are not checking manifest here. + local $SIG{__WARN__} = sub {1}; + require ExtUtils::Manifest; + local *ExtUtils::Manifest::manicheck = sub { return }; + + require Module::Build; + my $build = Module::Build->new( + dist_name => $self->name, + dist_version => $self->version, + license => $self->license, + ); + $self->provides( %{ $build->find_dist_packages || {} } ); +} + +sub feature { + my $self = shift; + my $name = shift; + my $features = ( $self->{values}->{features} ||= [] ); + my $mods; + + if ( @_ == 1 and ref( $_[0] ) ) { + # The user used ->feature like ->features by passing in the second + # argument as a reference. Accomodate for that. + $mods = $_[0]; + } else { + $mods = \@_; + } + + my $count = 0; + push @$features, ( + $name => [ + map { + ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ + } @$mods + ] + ); + + return @$features; +} + +sub features { + my $self = shift; + while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { + $self->feature( $name, @$mods ); + } + return $self->{values}->{features} + ? @{ $self->{values}->{features} } + : (); +} + +sub no_index { + my $self = shift; + my $type = shift; + push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; + return $self->{values}->{no_index}; +} + +sub read { + my $self = shift; + $self->include_deps( 'YAML::Tiny', 0 ); + + require YAML::Tiny; + my $data = YAML::Tiny::LoadFile('META.yml'); + + # Call methods explicitly in case user has already set some values. + while ( my ( $key, $value ) = each %$data ) { + next unless $self->can($key); + if ( ref $value eq 'HASH' ) { + while ( my ( $module, $version ) = each %$value ) { + $self->can($key)->($self, $module => $version ); + } + } else { + $self->can($key)->($self, $value); + } + } + return $self; +} + +sub write { + my $self = shift; + return $self unless $self->is_admin; + $self->admin->write_meta; + return $self; +} + +sub version_from { + require ExtUtils::MM_Unix; + my ( $self, $file ) = @_; + $self->version( ExtUtils::MM_Unix->parse_version($file) ); + + # for version integrity check + $self->makemaker_args( VERSION_FROM => $file ); +} + +sub abstract_from { + require ExtUtils::MM_Unix; + my ( $self, $file ) = @_; + $self->abstract( + bless( + { DISTNAME => $self->name }, + 'ExtUtils::MM_Unix' + )->parse_abstract($file) + ); +} + +# Add both distribution and module name +sub name_from { + my ($self, $file) = @_; + if ( + Module::Install::_read($file) =~ m/ + ^ \s* + package \s* + ([\w:]+) + \s* ; + /ixms + ) { + my ($name, $module_name) = ($1, $1); + $name =~ s{::}{-}g; + $self->name($name); + unless ( $self->module_name ) { + $self->module_name($module_name); + } + } else { + die("Cannot determine name from $file\n"); + } +} + +sub _extract_perl_version { + if ( + $_[0] =~ m/ + ^\s* + (?:use|require) \s* + v? + ([\d_\.]+) + \s* ; + /ixms + ) { + my $perl_version = $1; + $perl_version =~ s{_}{}g; + return $perl_version; + } else { + return; + } +} + +sub perl_version_from { + my $self = shift; + my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); + if ($perl_version) { + $self->perl_version($perl_version); + } else { + warn "Cannot determine perl version info from $_[0]\n"; + return; + } +} + +sub author_from { + my $self = shift; + my $content = Module::Install::_read($_[0]); + if ($content =~ m/ + =head \d \s+ (?:authors?)\b \s* + ([^\n]*) + | + =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* + .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* + ([^\n]*) + /ixms) { + my $author = $1 || $2; + + # XXX: ugly but should work anyway... + if (eval "require Pod::Escapes; 1") { + # Pod::Escapes has a mapping table. + # It's in core of perl >= 5.9.3, and should be installed + # as one of the Pod::Simple's prereqs, which is a prereq + # of Pod::Text 3.x (see also below). + $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } + { + defined $2 + ? chr($2) + : defined $Pod::Escapes::Name2character_number{$1} + ? chr($Pod::Escapes::Name2character_number{$1}) + : do { + warn "Unknown escape: E<$1>"; + "E<$1>"; + }; + }gex; + } + elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { + # Pod::Text < 3.0 has yet another mapping table, + # though the table name of 2.x and 1.x are different. + # (1.x is in core of Perl < 5.6, 2.x is in core of + # Perl < 5.9.3) + my $mapping = ($Pod::Text::VERSION < 2) + ? \%Pod::Text::HTML_Escapes + : \%Pod::Text::ESCAPES; + $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } + { + defined $2 + ? chr($2) + : defined $mapping->{$1} + ? $mapping->{$1} + : do { + warn "Unknown escape: E<$1>"; + "E<$1>"; + }; + }gex; + } + else { + $author =~ s{E}{<}g; + $author =~ s{E}{>}g; + } + $self->author($author); + } else { + warn "Cannot determine author info from $_[0]\n"; + } +} + +#Stolen from M::B +my %license_urls = ( + perl => 'http://dev.perl.org/licenses/', + apache => 'http://apache.org/licenses/LICENSE-2.0', + apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1', + artistic => 'http://opensource.org/licenses/artistic-license.php', + artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', + lgpl => 'http://opensource.org/licenses/lgpl-license.php', + lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', + lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', + bsd => 'http://opensource.org/licenses/bsd-license.php', + gpl => 'http://opensource.org/licenses/gpl-license.php', + gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', + gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', + mit => 'http://opensource.org/licenses/mit-license.php', + mozilla => 'http://opensource.org/licenses/mozilla1.1.php', + open_source => undef, + unrestricted => undef, + restrictive => undef, + unknown => undef, +); + +sub license { + my $self = shift; + return $self->{values}->{license} unless @_; + my $license = shift or die( + 'Did not provide a value to license()' + ); + $license = __extract_license($license) || lc $license; + $self->{values}->{license} = $license; + + # Automatically fill in license URLs + if ( $license_urls{$license} ) { + $self->resources( license => $license_urls{$license} ); + } + + return 1; +} + +sub _extract_license { + my $pod = shift; + my $matched; + return __extract_license( + ($matched) = $pod =~ m/ + (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?) + (=head \d.*|=cut.*|)\z + /xms + ) || __extract_license( + ($matched) = $pod =~ m/ + (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?) + (=head \d.*|=cut.*|)\z + /xms + ); +} + +sub __extract_license { + my $license_text = shift or return; + my @phrases = ( + '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1, + '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1, + 'Artistic and GPL' => 'perl', 1, + 'GNU general public license' => 'gpl', 1, + 'GNU public license' => 'gpl', 1, + 'GNU lesser general public license' => 'lgpl', 1, + 'GNU lesser public license' => 'lgpl', 1, + 'GNU library general public license' => 'lgpl', 1, + 'GNU library public license' => 'lgpl', 1, + 'GNU Free Documentation license' => 'unrestricted', 1, + 'GNU Affero General Public License' => 'open_source', 1, + '(?:Free)?BSD license' => 'bsd', 1, + 'Artistic license' => 'artistic', 1, + 'Apache (?:Software )?license' => 'apache', 1, + 'GPL' => 'gpl', 1, + 'LGPL' => 'lgpl', 1, + 'BSD' => 'bsd', 1, + 'Artistic' => 'artistic', 1, + 'MIT' => 'mit', 1, + 'Mozilla Public License' => 'mozilla', 1, + 'Q Public License' => 'open_source', 1, + 'OpenSSL License' => 'unrestricted', 1, + 'SSLeay License' => 'unrestricted', 1, + 'zlib License' => 'open_source', 1, + 'proprietary' => 'proprietary', 0, + ); + while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { + $pattern =~ s#\s+#\\s+#gs; + if ( $license_text =~ /\b$pattern\b/i ) { + return $license; + } + } + return ''; +} + +sub license_from { + my $self = shift; + if (my $license=_extract_license(Module::Install::_read($_[0]))) { + $self->license($license); + } else { + warn "Cannot determine license info from $_[0]\n"; + return 'unknown'; + } +} + +sub _extract_bugtracker { + my @links = $_[0] =~ m#L<( + \Qhttp://rt.cpan.org/\E[^>]+| + \Qhttp://github.com/\E[\w_]+/[\w_]+/issues| + \Qhttp://code.google.com/p/\E[\w_\-]+/issues/list + )>#gx; + my %links; + @links{@links}=(); + @links=keys %links; + return @links; +} + +sub bugtracker_from { + my $self = shift; + my $content = Module::Install::_read($_[0]); + my @links = _extract_bugtracker($content); + unless ( @links ) { + warn "Cannot determine bugtracker info from $_[0]\n"; + return 0; + } + if ( @links > 1 ) { + warn "Found more than one bugtracker link in $_[0]\n"; + return 0; + } + + # Set the bugtracker + bugtracker( $links[0] ); + return 1; +} + +sub requires_from { + my $self = shift; + my $content = Module::Install::_readperl($_[0]); + my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; + while ( @requires ) { + my $module = shift @requires; + my $version = shift @requires; + $self->requires( $module => $version ); + } +} + +sub test_requires_from { + my $self = shift; + my $content = Module::Install::_readperl($_[0]); + my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; + while ( @requires ) { + my $module = shift @requires; + my $version = shift @requires; + $self->test_requires( $module => $version ); + } +} + +# Convert triple-part versions (eg, 5.6.1 or 5.8.9) to +# numbers (eg, 5.006001 or 5.008009). +# Also, convert double-part versions (eg, 5.8) +sub _perl_version { + my $v = $_[-1]; + $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; + $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; + $v =~ s/(\.\d\d\d)000$/$1/; + $v =~ s/_.+$//; + if ( ref($v) ) { + # Numify + $v = $v + 0; + } + return $v; +} + +sub add_metadata { + my $self = shift; + my %hash = @_; + for my $key (keys %hash) { + warn "add_metadata: $key is not prefixed with 'x_'.\n" . + "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/; + $self->{values}->{$key} = $hash{$key}; + } +} + + +###################################################################### +# MYMETA Support + +sub WriteMyMeta { + die "WriteMyMeta has been deprecated"; +} + +sub write_mymeta_yaml { + my $self = shift; + + # We need YAML::Tiny to write the MYMETA.yml file + unless ( eval { require YAML::Tiny; 1; } ) { + return 1; + } + + # Generate the data + my $meta = $self->_write_mymeta_data or return 1; + + # Save as the MYMETA.yml file + print "Writing MYMETA.yml\n"; + YAML::Tiny::DumpFile('MYMETA.yml', $meta); +} + +sub write_mymeta_json { + my $self = shift; + + # We need JSON to write the MYMETA.json file + unless ( eval { require JSON; 1; } ) { + return 1; + } + + # Generate the data + my $meta = $self->_write_mymeta_data or return 1; + + # Save as the MYMETA.yml file + print "Writing MYMETA.json\n"; + Module::Install::_write( + 'MYMETA.json', + JSON->new->pretty(1)->canonical->encode($meta), + ); +} + +sub _write_mymeta_data { + my $self = shift; + + # If there's no existing META.yml there is nothing we can do + return undef unless -f 'META.yml'; + + # We need Parse::CPAN::Meta to load the file + unless ( eval { require Parse::CPAN::Meta; 1; } ) { + return undef; + } + + # Merge the perl version into the dependencies + my $val = $self->Meta->{values}; + my $perl = delete $val->{perl_version}; + if ( $perl ) { + $val->{requires} ||= []; + my $requires = $val->{requires}; + + # Canonize to three-dot version after Perl 5.6 + if ( $perl >= 5.006 ) { + $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e + } + unshift @$requires, [ perl => $perl ]; + } + + # Load the advisory META.yml file + my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); + my $meta = $yaml[0]; + + # Overwrite the non-configure dependency hashs + delete $meta->{requires}; + delete $meta->{build_requires}; + delete $meta->{recommends}; + if ( exists $val->{requires} ) { + $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; + } + if ( exists $val->{build_requires} ) { + $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; + } + + return $meta; +} + +1; diff --git a/api/perl/inc/Module/Install/Win32.pm b/api/perl/inc/Module/Install/Win32.pm new file mode 100644 index 0000000..edc18b4 --- /dev/null +++ b/api/perl/inc/Module/Install/Win32.pm @@ -0,0 +1,64 @@ +#line 1 +package Module::Install::Win32; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = 'Module::Install::Base'; + $ISCORE = 1; +} + +# determine if the user needs nmake, and download it if needed +sub check_nmake { + my $self = shift; + $self->load('can_run'); + $self->load('get_file'); + + require Config; + return unless ( + $^O eq 'MSWin32' and + $Config::Config{make} and + $Config::Config{make} =~ /^nmake\b/i and + ! $self->can_run('nmake') + ); + + print "The required 'nmake' executable not found, fetching it...\n"; + + require File::Basename; + my $rv = $self->get_file( + url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', + ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', + local_dir => File::Basename::dirname($^X), + size => 51928, + run => 'Nmake15.exe /o > nul', + check_for => 'Nmake.exe', + remove => 1, + ); + + die <<'END_MESSAGE' unless $rv; + +------------------------------------------------------------------------------- + +Since you are using Microsoft Windows, you will need the 'nmake' utility +before installation. It's available at: + + http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe + or + ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe + +Please download the file manually, save it to a directory in %PATH% (e.g. +C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to +that directory, and run "Nmake15.exe" from there; that will create the +'nmake.exe' file needed by this module. + +You may then resume the installation process described in README. + +------------------------------------------------------------------------------- +END_MESSAGE + +} + +1; diff --git a/api/perl/inc/Module/Install/WriteAll.pm b/api/perl/inc/Module/Install/WriteAll.pm new file mode 100644 index 0000000..d0f6599 --- /dev/null +++ b/api/perl/inc/Module/Install/WriteAll.pm @@ -0,0 +1,63 @@ +#line 1 +package Module::Install::WriteAll; + +use strict; +use Module::Install::Base (); + +use vars qw{$VERSION @ISA $ISCORE}; +BEGIN { + $VERSION = '1.00'; + @ISA = qw{Module::Install::Base}; + $ISCORE = 1; +} + +sub WriteAll { + my $self = shift; + my %args = ( + meta => 1, + sign => 0, + inline => 0, + check_nmake => 1, + @_, + ); + + $self->sign(1) if $args{sign}; + $self->admin->WriteAll(%args) if $self->is_admin; + + $self->check_nmake if $args{check_nmake}; + unless ( $self->makemaker_args->{PL_FILES} ) { + # XXX: This still may be a bit over-defensive... + unless ($self->makemaker(6.25)) { + $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; + } + } + + # Until ExtUtils::MakeMaker support MYMETA.yml, make sure + # we clean it up properly ourself. + $self->realclean_files('MYMETA.yml'); + + if ( $args{inline} ) { + $self->Inline->write; + } else { + $self->Makefile->write; + } + + # The Makefile write process adds a couple of dependencies, + # so write the META.yml files after the Makefile. + if ( $args{meta} ) { + $self->Meta->write; + } + + # Experimental support for MYMETA + if ( $ENV{X_MYMETA} ) { + if ( $ENV{X_MYMETA} eq 'JSON' ) { + $self->Meta->write_mymeta_json; + } else { + $self->Meta->write_mymeta_yaml; + } + } + + return 1; +} + +1; diff --git a/api/perl/lib/Monitoring/Livestatus.pm b/api/perl/lib/Monitoring/Livestatus.pm new file mode 100644 index 0000000..ce092ae --- /dev/null +++ b/api/perl/lib/Monitoring/Livestatus.pm @@ -0,0 +1,1564 @@ +package Monitoring::Livestatus; + +use 5.006; +use strict; +use warnings; +use Data::Dumper; +use Carp; +use Digest::MD5 qw(md5_hex); +use Monitoring::Livestatus::INET; +use Monitoring::Livestatus::UNIX; +use Monitoring::Livestatus::MULTI; +use Encode; +use JSON::XS; + +our $VERSION = '0.74'; + + +=head1 NAME + +Monitoring::Livestatus - Perl API for check_mk livestatus to access runtime +data from Nagios and Icinga + +=head1 SYNOPSIS + + use Monitoring::Livestatus; + my $ml = Monitoring::Livestatus->new( + socket => '/var/lib/livestatus/livestatus.sock' + ); + my $hosts = $ml->selectall_arrayref("GET hosts"); + +=head1 DESCRIPTION + +This module connects via socket/tcp to the check_mk livestatus addon for Nagios +and Icinga. You first have to install and activate the mklivestatus addon in your +monitoring installation. + +=head1 CONSTRUCTOR + +=head2 new ( [ARGS] ) + +Creates an C object. C takes at least the +socketpath. Arguments are in key-value pairs. +See L for more complex variants. + +=over 4 + +=item socket + +path to the UNIX socket of check_mk livestatus + +=item server + +use this server for a TCP connection + +=item peer + +alternative way to set socket or server, if value contains ':' server is used, +else socket + +=item name + +human readable name for this connection, defaults to the the socket/server +address + +=item verbose + +verbose mode + +=item line_seperator + +ascii code of the line seperator, defaults to 10, (newline) + +=item column_seperator + +ascii code of the column seperator, defaults to 0 (null byte) + +=item list_seperator + +ascii code of the list seperator, defaults to 44 (comma) + +=item host_service_seperator + +ascii code of the host/service seperator, defaults to 124 (pipe) + +=item keepalive + +enable keepalive. Default is off + +=item errors_are_fatal + +errors will die with an error message. Default: on + +=item warnings + +show warnings +currently only querys without Columns: Header will result in a warning + +=item timeout + +set a general timeout. Used for connect and querys, no default + +=item query_timeout + +set a query timeout. Used for retrieving querys, Default 60sec + +=item connect_timeout + +set a connect timeout. Used for initial connections, default 5sec + +=item use_threads + +only used with multiple backend connections. +Default is to don't threads where available. As threads in perl +are causing problems with tied resultset and using more memory. +Querys are usually faster without threads, except for very slow backends +connections. + +=back + +If the constructor is only passed a single argument, it is assumed to +be a the C specification. Use either socker OR server. + +=cut + +sub new { + my $class = shift; + unshift(@_, "peer") if scalar @_ == 1; + my(%options) = @_; + + my $self = { + "verbose" => 0, # enable verbose output + "socket" => undef, # use unix sockets + "server" => undef, # use tcp connections + "peer" => undef, # use for socket / server connections + "name" => undef, # human readable name + "line_seperator" => 10, # defaults to newline + "column_seperator" => 0, # defaults to null byte + "list_seperator" => 44, # defaults to comma + "host_service_seperator" => 124, # defaults to pipe + "keepalive" => 0, # enable keepalive? + "errors_are_fatal" => 1, # die on errors + "backend" => undef, # should be keept undef, used internally + "timeout" => undef, # timeout for tcp connections + "query_timeout" => 60, # query timeout for tcp connections + "connect_timeout" => 5, # connect timeout for tcp connections + "timeout" => undef, # timeout for tcp connections + "use_threads" => undef, # use threads, default is to use threads where available + "warnings" => 1, # show warnings, for example on querys without Column: Header + "logger" => undef, # logger object used for statistical informations and errors / warnings + "deepcopy" => undef, # copy result set to avoid errors with tied structures + "disabled" => 0, # if disabled, this peer will not receive any query + "retries_on_connection_error" => 3, # retry x times to connect + "retry_interval" => 1, # retry after x seconds + }; + + for my $opt_key (keys %options) { + if(exists $self->{$opt_key}) { + $self->{$opt_key} = $options{$opt_key}; + } + else { + croak("unknown option: $opt_key"); + } + } + + if($self->{'verbose'} and !defined $self->{'logger'}) { + croak('please specify a logger object when using verbose mode'); + $self->{'verbose'} = 0; + } + + # setting a general timeout? + if(defined $self->{'timeout'}) { + $self->{'query_timeout'} = $self->{'timeout'}; + $self->{'connect_timeout'} = $self->{'timeout'}; + } + + bless $self, $class; + + # set our peer(s) from the options + my $peers = $self->_get_peers(); + + if(!defined $peers) { + croak('please specify at least one peer, socket or server'); + } + + if(!defined $self->{'backend'}) { + if(scalar @{$peers} == 1) { + my $peer = $peers->[0]; + $options{'name'} = $peer->{'name'}; + $options{'peer'} = $peer->{'peer'}; + if($peer->{'type'} eq 'UNIX') { + $self->{'CONNECTOR'} = new Monitoring::Livestatus::UNIX(%options); + } + elsif($peer->{'type'} eq 'INET') { + $self->{'CONNECTOR'} = new Monitoring::Livestatus::INET(%options); + } + $self->{'peer'} = $peer->{'peer'}; + } + else { + $options{'peer'} = $peers; + return new Monitoring::Livestatus::MULTI(%options); + } + } + + # set names and peer for non multi backends + if(defined $self->{'CONNECTOR'}->{'name'} and !defined $self->{'name'}) { + $self->{'name'} = $self->{'CONNECTOR'}->{'name'}; + } + if(defined $self->{'CONNECTOR'}->{'peer'} and !defined $self->{'peer'}) { + $self->{'peer'} = $self->{'CONNECTOR'}->{'peer'}; + } + + if($self->{'verbose'} and (!defined $self->{'backend'} or $self->{'backend'} ne 'Monitoring::Livestatus::MULTI')) { + $self->{'logger'}->debug('initialized Monitoring::Livestatus ('.$self->peer_name.')'); + } + + return $self; +} + + +######################################## + +=head1 METHODS + +=head2 do + + do($statement) + do($statement, %opts) + +Send a single statement without fetching the result. +Always returns true. + +=cut + +sub do { + my $self = shift; + my $statement = shift; + return if $self->{'disabled'}; + $self->_send($statement); + return(1); +} + + +######################################## + +=head2 selectall_arrayref + + selectall_arrayref($statement) + selectall_arrayref($statement, %opts) + selectall_arrayref($statement, %opts, $limit ) + +Sends a query and returns an array reference of arrays + + my $arr_refs = $ml->selectall_arrayref("GET hosts"); + +to get an array of hash references do something like + + my $hash_refs = $ml->selectall_arrayref( + "GET hosts", { Slice => {} } + ); + +to get an array of hash references from the first 2 returned rows only + + my $hash_refs = $ml->selectall_arrayref( + "GET hosts", { Slice => {} }, 2 + ); + +use limit to limit the result to this number of rows + +column aliases can be defined with a rename hash + + my $hash_refs = $ml->selectall_arrayref( + "GET hosts", { + Slice => {}, + rename => { + 'name' => 'host_name' + } + } + ); + +=cut + +sub selectall_arrayref { + my $self = shift; + my $statement = shift; + my $opt = shift; + my $limit = shift || 0; + return if $self->{'disabled'}; + my $result; + + # make opt hash keys lowercase + $opt = $self->_lowercase_and_verify_options($opt); + + $self->_log_statement($statement, $opt, $limit) if $self->{'verbose'}; + + $result = $self->_send($statement, $opt); + + if(!defined $result) { + return unless $self->{'errors_are_fatal'}; + croak("got undef result for: $statement"); + } + + # trim result set down to excepted row count + if(defined $limit and $limit >= 1) { + if(scalar @{$result->{'result'}} > $limit) { + @{$result->{'result'}} = @{$result->{'result'}}[0..$limit-1]; + } + } + + if($opt->{'slice'}) { + # make an array of hashes + my @hash_refs; + for my $res (@{$result->{'result'}}) { + my $hash_ref; + for(my $x=0;$x{'keys'}->[$x]; + if(exists $opt->{'rename'} and defined $opt->{'rename'}->{$key}) { + $key = $opt->{'rename'}->{$key}; + } + $hash_ref->{$key} = $res->[$x]; + } + # add callbacks + if(exists $opt->{'callbacks'}) { + for my $key (keys %{$opt->{'callbacks'}}) { + $hash_ref->{$key} = $opt->{'callbacks'}->{$key}->($hash_ref); + } + } + push @hash_refs, $hash_ref; + } + return(\@hash_refs); + } + elsif(exists $opt->{'callbacks'}) { + for my $res (@{$result->{'result'}}) { + # add callbacks + if(exists $opt->{'callbacks'}) { + for my $key (keys %{$opt->{'callbacks'}}) { + push @{$res}, $opt->{'callbacks'}->{$key}->($res); + } + } + } + } + + if(exists $opt->{'callbacks'}) { + for my $key (keys %{$opt->{'callbacks'}}) { + push @{$result->{'keys'}}, $key; + } + } + + return($result->{'result'}); +} + + +######################################## + +=head2 selectall_hashref + + selectall_hashref($statement, $key_field) + selectall_hashref($statement, $key_field, %opts) + +Sends a query and returns a hashref with the given key + + my $hashrefs = $ml->selectall_hashref("GET hosts", "name"); + +=cut + +sub selectall_hashref { + my $self = shift; + my $statement = shift; + my $key_field = shift; + my $opt = shift; + + $opt = $self->_lowercase_and_verify_options($opt); + + $opt->{'slice'} = 1; + + croak("key is required for selectall_hashref") if !defined $key_field; + + my $result = $self->selectall_arrayref($statement, $opt); + + my %indexed; + for my $row (@{$result}) { + if($key_field eq '$peername') { + $indexed{$self->peer_name} = $row; + } + elsif(!defined $row->{$key_field}) { + my %possible_keys = keys %{$row}; + croak("key $key_field not found in result set, possible keys are: ".join(', ', sort keys %possible_keys)); + } else { + $indexed{$row->{$key_field}} = $row; + } + } + return(\%indexed); +} + + +######################################## + +=head2 selectcol_arrayref + + selectcol_arrayref($statement) + selectcol_arrayref($statement, %opt ) + +Sends a query an returns an arrayref for the first columns + + my $array_ref = $ml->selectcol_arrayref("GET hosts\nColumns: name"); + + $VAR1 = [ + 'localhost', + 'gateway', + ]; + +returns an empty array if nothing was found + +to get a different column use this + + my $array_ref = $ml->selectcol_arrayref( + "GET hosts\nColumns: name contacts", + { Columns => [2] } + ); + + you can link 2 columns in a hash result set + + my %hash = @{ + $ml->selectcol_arrayref( + "GET hosts\nColumns: name contacts", + { Columns => [1,2] } + ) + }; + +produces a hash with host the contact assosiation + + $VAR1 = { + 'localhost' => 'user1', + 'gateway' => 'user2' + }; + +=cut + +sub selectcol_arrayref { + my $self = shift; + my $statement = shift; + my $opt = shift; + + # make opt hash keys lowercase + $opt = $self->_lowercase_and_verify_options($opt); + + # if now colums are set, use just the first one + if(!defined $opt->{'columns'} or ref $opt->{'columns'} ne 'ARRAY') { + @{$opt->{'columns'}} = qw{1}; + } + + my $result = $self->selectall_arrayref($statement); + + my @column; + for my $row (@{$result}) { + for my $nr (@{$opt->{'columns'}}) { + push @column, $row->[$nr-1]; + } + } + return(\@column); +} + + +######################################## + +=head2 selectrow_array + + selectrow_array($statement) + selectrow_array($statement, %opts) + +Sends a query and returns an array for the first row + + my @array = $ml->selectrow_array("GET hosts"); + +returns undef if nothing was found + +=cut +sub selectrow_array { + my $self = shift; + my $statement = shift; + my $opt = shift; + + # make opt hash keys lowercase + $opt = $self->_lowercase_and_verify_options($opt); + + my @result = @{$self->selectall_arrayref($statement, $opt, 1)}; + return @{$result[0]} if scalar @result > 0; + return; +} + + +######################################## + +=head2 selectrow_arrayref + + selectrow_arrayref($statement) + selectrow_arrayref($statement, %opts) + +Sends a query and returns an array reference for the first row + + my $arrayref = $ml->selectrow_arrayref("GET hosts"); + +returns undef if nothing was found + +=cut +sub selectrow_arrayref { + my $self = shift; + my $statement = shift; + my $opt = shift; + + # make opt hash keys lowercase + $opt = $self->_lowercase_and_verify_options($opt); + + my $result = $self->selectall_arrayref($statement, $opt, 1); + return if !defined $result; + return $result->[0] if scalar @{$result} > 0; + return; +} + + +######################################## + +=head2 selectrow_hashref + + selectrow_hashref($statement) + selectrow_hashref($statement, %opt) + +Sends a query and returns a hash reference for the first row + + my $hashref = $ml->selectrow_hashref("GET hosts"); + +returns undef if nothing was found + +=cut +sub selectrow_hashref { + my $self = shift; + my $statement = shift; + my $opt = shift; + + # make opt hash keys lowercase + $opt = $self->_lowercase_and_verify_options($opt); + $opt->{slice} = 1; + + my $result = $self->selectall_arrayref($statement, $opt, 1); + return if !defined $result; + return $result->[0] if scalar @{$result} > 0; + return; +} + + +######################################## + +=head2 selectscalar_value + + selectscalar_value($statement) + selectscalar_value($statement, %opt) + +Sends a query and returns a single scalar + + my $count = $ml->selectscalar_value("GET hosts\nStats: state = 0"); + +returns undef if nothing was found + +=cut +sub selectscalar_value { + my $self = shift; + my $statement = shift; + my $opt = shift; + + # make opt hash keys lowercase + $opt = $self->_lowercase_and_verify_options($opt); + + my $row = $self->selectrow_arrayref($statement); + return if !defined $row; + return $row->[0] if scalar @{$row} > 0; + return; +} + +######################################## + +=head2 errors_are_fatal + + errors_are_fatal() + errors_are_fatal($value) + +Enable or disable fatal errors. When enabled the module will croak on any error. + +returns the current setting if called without new value + +=cut +sub errors_are_fatal { + my $self = shift; + my $value = shift; + my $old = $self->{'errors_are_fatal'}; + + $self->{'errors_are_fatal'} = $value; + $self->{'CONNECTOR'}->{'errors_are_fatal'} = $value if defined $self->{'CONNECTOR'}; + + return $old; +} + +######################################## + +=head2 warnings + + warnings() + warnings($value) + +Enable or disable warnings. When enabled the module will carp on warnings. + +returns the current setting if called without new value + +=cut +sub warnings { + my $self = shift; + my $value = shift; + my $old = $self->{'warnings'}; + + $self->{'warnings'} = $value; + $self->{'CONNECTOR'}->{'warnings'} = $value if defined $self->{'CONNECTOR'}; + + return $old; +} + + + +######################################## + +=head2 verbose + + verbose() + verbose($values) + +Enable or disable verbose output. When enabled the module will dump out debug output + +returns the current setting if called without new value + +=cut +sub verbose { + my $self = shift; + my $value = shift; + my $old = $self->{'verbose'}; + + $self->{'verbose'} = $value; + $self->{'CONNECTOR'}->{'verbose'} = $value if defined $self->{'CONNECTOR'}; + + return $old; +} + + +######################################## + +=head2 peer_addr + + $ml->peer_addr() + +returns the current peer address + +when using multiple backends, a list of all addresses is returned in list context + +=cut +sub peer_addr { + my $self = shift; + + return "".$self->{'peer'}; +} + + +######################################## + +=head2 peer_name + + $ml->peer_name() + $ml->peer_name($string) + +if new value is set, name is set to this value + +always returns the current peer name + +when using multiple backends, a list of all names is returned in list context + +=cut +sub peer_name { + my $self = shift; + my $value = shift; + + if(defined $value and $value ne '') { + $self->{'name'} = $value; + } + + return "".$self->{'name'}; +} + + +######################################## + +=head2 peer_key + + $ml->peer_key() + +returns a uniq key for this peer + +when using multiple backends, a list of all keys is returned in list context + +=cut +sub peer_key { + my $self = shift; + + if(!defined $self->{'key'}) { $self->{'key'} = md5_hex($self->peer_addr." ".$self->peer_name); } + + return $self->{'key'}; +} + + +######################################## + +=head2 marked_bad + + $ml->marked_bad() + +returns true if the current connection is marked down + +=cut +sub marked_bad { + my $self = shift; + + return 0; +} + + +######################################## + +=head2 disable + + $ml->disable() + +disables this connection, returns the last state. + +=cut +sub disable { + my $self = shift; + my $prev = $self->{'disabled'}; + $self->{'disabled'} = 1; + return $prev; +} + + +######################################## + +=head2 enable + + $ml->enable() + +enables this connection, returns the last state. + +=cut +sub enable { + my $self = shift; + my $prev = $self->{'disabled'}; + $self->{'disabled'} = 0; + return $prev; +} + +######################################## +# INTERNAL SUBS +######################################## +sub _send { + my $self = shift; + my $statement = shift; + my $opt = shift; + + delete $self->{'meta_data'}; + + my $header = ""; + my $keys; + + my $with_peers = 0; + if(defined $opt->{'addpeer'} and $opt->{'addpeer'}) { + $with_peers = 1; + } + + $Monitoring::Livestatus::ErrorCode = 0; + undef $Monitoring::Livestatus::ErrorMessage; + + return(490, $self->_get_error(490), undef) if !defined $statement; + chomp($statement); + + my($status,$msg,$body); + if($statement =~ m/^Separators:/mx) { + $status = 492; + $msg = $self->_get_error($status); + } + + elsif($statement =~ m/^KeepAlive:/mx) { + $status = 496; + $msg = $self->_get_error($status); + } + + elsif($statement =~ m/^ResponseHeader:/mx) { + $status = 495; + $msg = $self->_get_error($status); + } + + elsif($statement =~ m/^ColumnHeaders:/mx) { + $status = 494; + $msg = $self->_get_error($status); + } + + elsif($statement =~ m/^OuputFormat:/mx) { + $status = 493; + $msg = $self->_get_error($status); + } + + # should be cought in mlivestatus directly + elsif($statement =~ m/^Limit:\ (.*)$/mx and $1 !~ m/^\d+$/mx) { + $status = 403; + $msg = $self->_get_error($status); + } + elsif($statement =~ m/^GET\ (.*)$/mx and $1 =~ m/^\s*$/mx) { + $status = 403; + $msg = $self->_get_error($status); + } + + elsif($statement =~ m/^Columns:\ (.*)$/mx and ($1 =~ m/,/mx or $1 =~ /^\s*$/mx)) { + $status = 405; + $msg = $self->_get_error($status); + } + elsif($statement !~ m/^GET\ /mx and $statement !~ m/^COMMAND\ /mx) { + $status = 401; + $msg = $self->_get_error($status); + } + + else { + + # Add Limits header + if(defined $opt->{'limit_start'}) { + $statement .= "\nLimit: ".($opt->{'limit_start'} + $opt->{'limit_length'}); + } + + # for querys with column header, no seperate columns will be returned + if($statement =~ m/^Columns:\ (.*)$/mx) { + ($statement,$keys) = $self->_extract_keys_from_columns_header($statement); + } elsif($statement =~ m/^Stats:\ (.*)$/mx or $statement =~ m/^StatsGroupBy:\ (.*)$/mx) { + ($statement,$keys) = $self->_extract_keys_from_stats_statement($statement); + } + + # Commands need no additional header + if($statement !~ m/^COMMAND/mx) { + $header .= "OutputFormat: json\n"; + $header .= "ResponseHeader: fixed16\n"; + if($self->{'keepalive'}) { + $header .= "KeepAlive: on\n"; + } + # remove empty lines from statement + $statement =~ s/\n+/\n/gmx; + } + + # add additional headers + if(defined $opt->{'header'} and ref $opt->{'header'} eq 'HASH') { + for my $key ( keys %{$opt->{'header'}}) { + $header .= $key.": ".$opt->{'header'}->{$key}."\n"; + } + } + + chomp($statement); + my $send = "$statement\n$header"; + $self->{'logger'}->debug("> ".Dumper($send)) if $self->{'verbose'}; + ($status,$msg,$body) = $self->_send_socket($send); + if($self->{'verbose'}) { + #$self->{'logger'}->debug("got:"); + #$self->{'logger'}->debug(Dumper(\@erg)); + $self->{'logger'}->debug("status: ".Dumper($status)); + $self->{'logger'}->debug("msg: ".Dumper($msg)); + $self->{'logger'}->debug("< ".Dumper($body)); + } + } + + if($status >= 300) { + $body = '' if !defined $body; + chomp($body); + $Monitoring::Livestatus::ErrorCode = $status; + if(defined $body and $body ne '') { + $Monitoring::Livestatus::ErrorMessage = $body; + } else { + $Monitoring::Livestatus::ErrorMessage = $msg; + } + $self->{'logger'}->error($status." - ".$Monitoring::Livestatus::ErrorMessage." in query:\n'".$statement) if $self->{'verbose'}; + if($self->{'errors_are_fatal'}) { + croak("ERROR ".$status." - ".$Monitoring::Livestatus::ErrorMessage." in query:\n'".$statement."'\n"); + } + return; + } + + # return a empty result set if nothing found + return({ keys => [], result => []}) if !defined $body; + + my $line_seperator = chr($self->{'line_seperator'}); + my $col_seperator = chr($self->{'column_seperator'}); + + my $peer_name = $self->peer_name; + my $peer_addr = $self->peer_addr; + my $peer_key = $self->peer_key; + + my $limit_start = 0; + if(defined $opt->{'limit_start'}) { $limit_start = $opt->{'limit_start'}; } + my $result; + # fix json output + $body =~ s/\],\n\]\n$/]]/mx; + eval { + $result = decode_json($body); + }; + if($@) { + my $message = "ERROR ".$@." in text: '".$body."'\" for statement: '$statement'\n"; + $self->{'logger'}->error($message) if $self->{'verbose'}; + if($self->{'errors_are_fatal'}) { + croak($message); + } + } + + # for querys with column header, no separate columns will be returned + if(!defined $keys) { + $self->{'logger'}->warn("got statement without Columns: header!") if $self->{'verbose'}; + if($self->{'warnings'}) { + carp("got statement without Columns: header! -> ".$statement); + } + $keys = shift @{$result}; + } + + # add peer information? + if(defined $with_peers and $with_peers == 1) { + unshift @{$keys}, 'peer_name'; + unshift @{$keys}, 'peer_addr'; + unshift @{$keys}, 'peer_key'; + + for my $row (@{$result}) { + unshift @{$row}, $peer_name; + unshift @{$row}, $peer_addr; + unshift @{$row}, $peer_key; + } + } + + # set some metadata + $self->{'meta_data'} = { + 'result_count' => scalar @${result}, + }; + + return({ keys => $keys, result => $result }); +} + +######################################## +sub _open { + my $self = shift; + my $statement = shift; + + # return the current socket in keep alive mode + if($self->{'keepalive'} and defined $self->{'sock'} and $self->{'sock'}->connected) { + $self->{'logger'}->debug("reusing old connection") if $self->{'verbose'}; + return($self->{'sock'}); + } + + my $sock = $self->{'CONNECTOR'}->_open(); + + # store socket for later retrieval + if($self->{'keepalive'}) { + $self->{'sock'} = $sock; + } + + $self->{'logger'}->debug("using new connection") if $self->{'verbose'}; + return($sock); +} + +######################################## +sub _close { + my $self = shift; + my $sock = shift; + undef $self->{'sock'}; + return($self->{'CONNECTOR'}->_close($sock)); +} + + +######################################## + +=head1 QUERY OPTIONS + +In addition to the normal query syntax from the livestatus addon, it is +possible to set column aliases in various ways. + +=head2 AddPeer + +adds the peers name, addr and key to the result set: + + my $hosts = $ml->selectall_hashref( + "GET hosts\nColumns: name alias state", + "name", + { AddPeer => 1 } + ); + +=head2 Backend + +send the query only to some specific backends. Only +useful when using multiple backends. + + my $hosts = $ml->selectall_arrayref( + "GET hosts\nColumns: name alias state", + { Backends => [ 'key1', 'key4' ] } + ); + +=head2 Columns + + only return the given column indexes + + my $array_ref = $ml->selectcol_arrayref( + "GET hosts\nColumns: name contacts", + { Columns => [2] } + ); + + see L for more examples + +=head2 Deepcopy + + deep copy/clone the result set. + + Only effective when using multiple backends and threads. + This can be safely turned off if you dont change the + result set. + If you get an error like "Invalid value for shared scalar" error" this + should be turned on. + + my $array_ref = $ml->selectcol_arrayref( + "GET hosts\nColumns: name contacts", + { Deepcopy => 1 } + ); + +=head2 Limit + + Just like the Limit: option from livestatus itself. + In addition you can add a start,length limit. + + my $array_ref = $ml->selectcol_arrayref( + "GET hosts\nColumns: name contacts", + { Limit => "10,20" } + ); + + This example will return 20 rows starting at row 10. You will + get row 10-30. + + Cannot be combined with a Limit inside the query + because a Limit will be added automatically. + + Adding a limit this way will greatly increase performance and + reduce memory usage. + + This option is multibackend safe contrary to the "Limit: " part of a statement. + Sending a statement like "GET...Limit: 10" with 3 backends will result in 30 rows. + Using this options, you will receive only the first 10 rows. + +=head2 Rename + + see L for detailed explainaton + +=head2 Slice + + see L for detailed explainaton + +=head2 Sum + +The Sum option only applies when using multiple backends. +The values from all backends with be summed up to a total. + + my $stats = $ml->selectrow_hashref( + "GET hosts\nStats: state = 0\nStats: state = 1", + { Sum => 1 } + ); + +=cut + + +######################################## +# wrapper around _send_socket_do +sub _send_socket { + my $self = shift; + my $statement = shift; + + my $retries = 0; + my($status, $msg, $recv); + + + # try to avoid connection errors + eval { + local $SIG{PIPE} = sub { + die("broken pipe"); + $self->{'logger'}->debug("broken pipe, closing socket") if $self->{'verbose'}; + $self->_close($self->{'sock'}); + }; + + if($self->{'retries_on_connection_error'} <= 0) { + ($status, $msg, $recv) = $self->_send_socket_do($statement); + return; + } + + while((!defined $status or ($status == 491 or $status == 497 or $status == 500)) and $retries < $self->{'retries_on_connection_error'}) { + $retries++; + ($status, $msg, $recv) = $self->_send_socket_do($statement); + $self->{'logger'}->debug('query status '.$status) if $self->{'verbose'}; + if($status == 491 or $status == 497 or $status == 500) { + $self->{'logger'}->debug('got status '.$status.' retrying in '.$self->{'retry_interval'}.' seconds') if $self->{'verbose'}; + $self->_close(); + sleep($self->{'retry_interval'}) if $retries < $self->{'retries_on_connection_error'}; + } + } + }; + if($@) { + $self->{'logger'}->debug("try 1 failed: $@") if $self->{'verbose'}; + if(defined $@ and $@ =~ /broken\ pipe/mx) { + return $self->_send_socket_do($statement); + } + croak($@) if $self->{'errors_are_fatal'}; + } + + croak($msg) if($status >= 400 and $self->{'errors_are_fatal'}); + + return($status, $msg, $recv); +} + +######################################## +sub _send_socket_do { + my $self = shift; + my $statement = shift; + my($recv,$header); + + my $sock = $self->_open() or return(491, $self->_get_error(491), $!); + utf8::decode($statement); + print $sock encode('utf-8' => $statement) or return($self->_socket_error($statement, $sock, 'write to socket failed: '.$!)); + + print $sock "\n"; + + # COMMAND statements never return something + if($statement =~ m/^COMMAND/mx) { + return('201', $self->_get_error(201), undef); + } + + $sock->read($header, 16) or return($self->_socket_error($statement, $sock, 'reading header from socket failed, check your livestatus logfile: '.$!)); + $self->{'logger'}->debug("header: $header") if $self->{'verbose'}; + my($status, $msg, $content_length) = $self->_parse_header($header, $sock); + return($status, $msg, undef) if !defined $content_length; + if($content_length > 0) { + $sock->read($recv, $content_length) or return($self->_socket_error($statement, $sock, 'reading body from socket failed')); + } + + $self->_close($sock) unless $self->{'keepalive'}; + return($status, $msg, $recv); +} + +######################################## +sub _socket_error { + my $self = shift; + my $statement = shift; + my $sock = shift; + my $body = shift; + + my $message = "\n"; + $message .= "peer ".Dumper($self->peer_name); + $message .= "statement ".Dumper($statement); + $message .= "message ".Dumper($body); + + $self->{'logger'}->error($message) if $self->{'verbose'}; + + if($self->{'retries_on_connection_error'} <= 0) { + if($self->{'errors_are_fatal'}) { + croak($message); + } + else { + carp($message); + } + } + $self->_close(); + return(500, $self->_get_error(500), $message); +} + +######################################## +sub _parse_header { + my $self = shift; + my $header = shift; + my $sock = shift; + + if(!defined $header) { + return(497, $self->_get_error(497), undef); + } + + my $headerlength = length($header); + if($headerlength != 16) { + return(498, $self->_get_error(498)."\ngot: ".$header.<$sock>, undef); + } + chomp($header); + + my $status = substr($header,0,3); + my $content_length = substr($header,5); + if($content_length !~ m/^\s*(\d+)$/mx) { + return(499, $self->_get_error(499)."\ngot: ".$header.<$sock>, undef); + } else { + $content_length = $1; + } + + return($status, $self->_get_error($status), $content_length); +} + +######################################## + +=head1 COLUMN ALIAS + +In addition to the normal query syntax from the livestatus addon, it is +possible to set column aliases in various ways. + +A valid Columns: Header could look like this: + + my $hosts = $ml->selectall_arrayref( + "GET hosts\nColumns: state as status" + ); + +Stats queries could be aliased too: + + my $stats = $ml->selectall_arrayref( + "GET hosts\nStats: state = 0 as up" + ); + +This syntax is available for: Stats, StatsAnd, StatsOr and StatsGroupBy + + +An alternative way to set column aliases is to define rename option key/value +pairs: + + my $hosts = $ml->selectall_arrayref( + "GET hosts\nColumns: name", { + rename => { 'name' => 'hostname' } + } + ); + +=cut + +######################################## +sub _extract_keys_from_stats_statement { + my $self = shift; + my $statement = shift; + + my(@header, $new_statement); + + for my $line (split/\n/mx, $statement) { + if($line =~ m/^Stats:\ (.*)\s+as\s+(.*)$/mxi) { + push @header, $2; + $line = 'Stats: '.$1; + } + elsif($line =~ m/^Stats:\ (.*)$/mx) { + push @header, $1; + } + + if($line =~ m/^StatsAnd:\ (\d+)\s+as\s+(.*)$/mx) { + for(my $x = 0; $x < $1; $x++) { + pop @header; + } + $line = 'StatsAnd: '.$1; + push @header, $2; + } + elsif($line =~ m/^StatsAnd:\ (\d+)$/mx) { + my @to_join; + for(my $x = 0; $x < $1; $x++) { + unshift @to_join, pop @header; + } + push @header, join(' && ', @to_join); + } + + if($line =~ m/^StatsOr:\ (\d+)\s+as\s+(.*)$/mx) { + for(my $x = 0; $x < $1; $x++) { + pop @header; + } + $line = 'StatsOr: '.$1; + push @header, $2; + } + elsif($line =~ m/^StatsOr:\ (\d+)$/mx) { + my @to_join; + for(my $x = 0; $x < $1; $x++) { + unshift @to_join, pop @header; + } + push @header, join(' || ', @to_join); + } + + # StatsGroupBy header are always sent first + if($line =~ m/^StatsGroupBy:\ (.*)\s+as\s+(.*)$/mxi) { + unshift @header, $2; + $line = 'StatsGroupBy: '.$1; + } + elsif($line =~ m/^StatsGroupBy:\ (.*)$/mx) { + unshift @header, $1; + } + $new_statement .= $line."\n"; + } + + return($new_statement, \@header); +} + +######################################## +sub _extract_keys_from_columns_header { + my $self = shift; + my $statement = shift; + + my(@header, $new_statement); + for my $line (split/\n/mx, $statement) { + if($line =~ m/^Columns:\s+(.*)$/mx) { + for my $column (split/\s+/mx, $1) { + if($column eq 'as') { + pop @header; + } else { + push @header, $column; + } + } + $line =~ s/\s+as\s+([^\s]+)/\ /gmx; + } + $new_statement .= $line."\n"; + } + + return($new_statement, \@header); +} + +######################################## + +=head1 ERROR HANDLING + +Errorhandling can be done like this: + + use Monitoring::Livestatus; + my $ml = Monitoring::Livestatus->new( + socket => '/var/lib/livestatus/livestatus.sock' + ); + $ml->errors_are_fatal(0); + my $hosts = $ml->selectall_arrayref("GET hosts"); + if($Monitoring::Livestatus::ErrorCode) { + croak($Monitoring::Livestatus::ErrorMessage); + } + +=cut +sub _get_error { + my $self = shift; + my $code = shift; + + my $codes = { + '200' => 'OK. Reponse contains the queried data.', + '201' => 'COMMANDs never return something', + '400' => 'The request contains an invalid header.', + '401' => 'The request contains an invalid header.', + '402' => 'The request is completely invalid.', + '403' => 'The request is incomplete.', + '404' => 'The target of the GET has not been found (e.g. the table).', + '405' => 'A non-existing column was being referred to', + '490' => 'no query', + '491' => 'failed to connect', + '492' => 'Separators not allowed in statement. Please use the seperator options in new()', + '493' => 'OuputFormat not allowed in statement. Header will be set automatically', + '494' => 'ColumnHeaders not allowed in statement. Header will be set automatically', + '495' => 'ResponseHeader not allowed in statement. Header will be set automatically', + '496' => 'Keepalive not allowed in statement. Please use the keepalive option in new()', + '497' => 'got no header', + '498' => 'header is not exactly 16byte long', + '499' => 'not a valid header (no content-length)', + '500' => 'socket error', + }; + + confess('non existant error code: '.$code) if !defined $codes->{$code}; + + return($codes->{$code}); +} + +######################################## +sub _get_peers { + my $self = shift; + + # set options for our peer(s) + my %options; + for my $opt_key (keys %{$self}) { + $options{$opt_key} = $self->{$opt_key}; + } + + my $peers = []; + + # check if the supplied peer is a socket or a server address + if(defined $self->{'peer'}) { + if(ref $self->{'peer'} eq '') { + my $name = $self->{'name'} || "".$self->{'peer'}; + if(index($self->{'peer'}, ':') > 0) { + push @{$peers}, { 'peer' => "".$self->{'peer'}, type => 'INET', name => $name }; + } else { + push @{$peers}, { 'peer' => "".$self->{'peer'}, type => 'UNIX', name => $name }; + } + } + elsif(ref $self->{'peer'} eq 'ARRAY') { + for my $peer (@{$self->{'peer'}}) { + if(ref $peer eq 'HASH') { + next if !defined $peer->{'peer'}; + $peer->{'name'} = "".$peer->{'peer'} unless defined $peer->{'name'}; + if(!defined $peer->{'type'}) { + $peer->{'type'} = 'UNIX'; + if(index($peer->{'peer'}, ':') >= 0) { + $peer->{'type'} = 'INET'; + } + } + push @{$peers}, $peer; + } else { + my $type = 'UNIX'; + if(index($peer, ':') >= 0) { + $type = 'INET'; + } + push @{$peers}, { 'peer' => "".$peer, type => $type, name => "".$peer }; + } + } + } + elsif(ref $self->{'peer'} eq 'HASH') { + for my $peer (keys %{$self->{'peer'}}) { + my $name = $self->{'peer'}->{$peer}; + my $type = 'UNIX'; + if(index($peer, ':') >= 0) { + $type = 'INET'; + } + push @{$peers}, { 'peer' => "".$peer, type => $type, name => "".$name }; + } + } else { + confess("type ".(ref $self->{'peer'})." is not supported for peer option"); + } + } + if(defined $self->{'socket'}) { + my $name = $self->{'name'} || "".$self->{'socket'}; + push @{$peers}, { 'peer' => "".$self->{'socket'}, type => 'UNIX', name => $name }; + } + if(defined $self->{'server'}) { + my $name = $self->{'name'} || "".$self->{'server'}; + push @{$peers}, { 'peer' => "".$self->{'server'}, type => 'INET', name => $name }; + } + + # check if we got a peer + if(scalar @{$peers} == 0) { + croak('please specify at least one peer, socket or server'); + } + + # clean up + delete $options{'peer'}; + delete $options{'socket'}; + delete $options{'server'}; + + return $peers; +} + + +######################################## +sub _lowercase_and_verify_options { + my $self = shift; + my $opts = shift; + my $return = {}; + + # list of allowed options + my $allowed_options = { + 'addpeer' => 1, + 'backend' => 1, + 'columns' => 1, + 'deepcopy' => 1, + 'header' => 1, + 'limit' => 1, + 'limit_start' => 1, + 'limit_length' => 1, + 'rename' => 1, + 'slice' => 1, + 'sum' => 1, + 'callbacks' => 1, + }; + + for my $key (keys %{$opts}) { + if($self->{'warnings'} and !defined $allowed_options->{lc $key}) { + carp("unknown option used: $key - please use only: ".join(", ", keys %{$allowed_options})); + } + $return->{lc $key} = $opts->{$key}; + } + + # set limits + if(defined $return->{'limit'}) { + if(index($return->{'limit'}, ',') != -1) { + my($limit_start,$limit_length) = split /,/mx, $return->{'limit'}; + $return->{'limit_start'} = $limit_start; + $return->{'limit_length'} = $limit_length; + } + else { + $return->{'limit_start'} = 0; + $return->{'limit_length'} = $return->{'limit'}; + } + delete $return->{'limit'}; + } + + return($return); +} + +######################################## +sub _log_statement { + my $self = shift; + my $statement = shift; + my $opt = shift; + my $limit = shift; + my $d = Data::Dumper->new([$opt]); + $d->Indent(0); + my $optstring = $d->Dump; + $optstring =~ s/^\$VAR1\s+=\s+//mx; + $optstring =~ s/;$//mx; + + # remove empty lines from statement + $statement =~ s/\n+/\n/gmx; + + my $cleanstatement = $statement; + $cleanstatement =~ s/\n/\\n/gmx; + $self->{'logger'}->debug('selectall_arrayref("'.$cleanstatement.'", '.$optstring.', '.$limit.')'); + return 1; +} + +######################################## + +1; + +=head1 EXAMPLES + +=head2 Multibackend Configuration + + use Monitoring::Livestatus; + my $ml = Monitoring::Livestatus->new( + name => 'multiple connector', + verbose => 0, + keepalive => 1, + peer => [ + { + name => 'DMZ Monitoring', + peer => '50.50.50.50:9999', + }, + { + name => 'Local Monitoring', + peer => '/tmp/livestatus.socket', + }, + { + name => 'Special Monitoring', + peer => '100.100.100.100:9999', + } + ], + ); + my $hosts = $ml->selectall_arrayref("GET hosts"); + +=head1 SEE ALSO + +For more information about the query syntax and the livestatus plugin installation +see the Livestatus page: http://mathias-kettner.de/checkmk_livestatus.html + +=head1 AUTHOR + +Sven Nierlein, Enierlein@cpan.orgE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2009 by Sven Nierlein + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__END__ diff --git a/api/perl/lib/Monitoring/Livestatus/INET.pm b/api/perl/lib/Monitoring/Livestatus/INET.pm new file mode 100644 index 0000000..2c01ebc --- /dev/null +++ b/api/perl/lib/Monitoring/Livestatus/INET.pm @@ -0,0 +1,121 @@ +package Monitoring::Livestatus::INET; + +use 5.000000; +use strict; +use warnings; +use IO::Socket::INET; +use Socket qw(IPPROTO_TCP TCP_NODELAY); +use Carp; +use base "Monitoring::Livestatus"; + +=head1 NAME + +Monitoring::Livestatus::INET - connector with tcp sockets + +=head1 SYNOPSIS + + use Monitoring::Livestatus; + my $nl = Monitoring::Livestatus::INET->new( 'localhost:9999' ); + my $hosts = $nl->selectall_arrayref("GET hosts"); + +=head1 CONSTRUCTOR + +=head2 new ( [ARGS] ) + +Creates an C object. C takes at least the server. +Arguments are the same as in C. +If the constructor is only passed a single argument, it is assumed to +be a the C specification. Use either socker OR server. + +=cut + +sub new { + my $class = shift; + unshift(@_, "peer") if scalar @_ == 1; + my(%options) = @_; + $options{'name'} = $options{'peer'} unless defined $options{'name'}; + + $options{'backend'} = $class; + my $self = Monitoring::Livestatus->new(%options); + bless $self, $class; + confess('not a scalar') if ref $self->{'peer'} ne ''; + + return $self; +} + + +######################################## + +=head1 METHODS + +=cut + +sub _open { + my $self = shift; + my $sock; + + eval { + local $SIG{'ALRM'} = sub { die("connection timeout"); }; + alarm($self->{'connect_timeout'}); + $sock = IO::Socket::INET->new( + PeerAddr => $self->{'peer'}, + Type => SOCK_STREAM, + Timeout => $self->{'connect_timeout'}, + ); + if(!defined $sock or !$sock->connected()) { + my $msg = "failed to connect to $self->{'peer'} :$!"; + if($self->{'errors_are_fatal'}) { + croak($msg); + } + $Monitoring::Livestatus::ErrorCode = 500; + $Monitoring::Livestatus::ErrorMessage = $msg; + alarm(0); + return; + } + + if(defined $self->{'query_timeout'}) { + # set timeout + $sock->timeout($self->{'query_timeout'}); + } + + setsockopt($sock, IPPROTO_TCP, TCP_NODELAY, 1); + + }; + alarm(0); + + if($@) { + $Monitoring::Livestatus::ErrorCode = 500; + $Monitoring::Livestatus::ErrorMessage = $@; + return; + } + + return($sock); +} + + +######################################## + +sub _close { + my $self = shift; + my $sock = shift; + return unless defined $sock; + return close($sock); +} + + +1; + +=head1 AUTHOR + +Sven Nierlein, Enierlein@cpan.orgE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2009 by Sven Nierlein + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__END__ diff --git a/api/perl/lib/Monitoring/Livestatus/MULTI.pm b/api/perl/lib/Monitoring/Livestatus/MULTI.pm new file mode 100644 index 0000000..20201bf --- /dev/null +++ b/api/perl/lib/Monitoring/Livestatus/MULTI.pm @@ -0,0 +1,922 @@ +package Monitoring::Livestatus::MULTI; + +use 5.000000; +use strict; +use warnings; +use Carp; +use Data::Dumper; +use Config; +use Time::HiRes qw/gettimeofday tv_interval/; +use Scalar::Util qw/looks_like_number/; +use Monitoring::Livestatus; +use base "Monitoring::Livestatus"; + +=head1 NAME + +Monitoring::Livestatus::MULTI - connector with multiple peers + +=head1 SYNOPSIS + + use Monitoring::Livestatus; + my $nl = Monitoring::Livestatus::MULTI->new( qw{nagioshost1:9999 nagioshost2:9999 /var/spool/nagios/live.socket} ); + my $hosts = $nl->selectall_arrayref("GET hosts"); + +=head1 CONSTRUCTOR + +=head2 new ( [ARGS] ) + +Creates an C object. C takes at least the server. +Arguments are the same as in L. + +=cut + +sub new { + my $class = shift; + unshift(@_, "peer") if scalar @_ == 1; + my(%options) = @_; + + $options{'backend'} = $class; + my $self = Monitoring::Livestatus->new(%options); + bless $self, $class; + + if(!defined $self->{'peers'}) { + $self->{'peer'} = $self->_get_peers(); + + # set our peer(s) from the options + my %peer_options; + my $peers; + for my $opt_key (keys %options) { + $peer_options{$opt_key} = $options{$opt_key}; + } + $peer_options{'errors_are_fatal'} = 0; + for my $peer (@{$self->{'peer'}}) { + $peer_options{'name'} = $peer->{'name'}; + $peer_options{'peer'} = $peer->{'peer'}; + delete $peer_options{'socket'}; + delete $peer_options{'server'}; + + if($peer->{'type'} eq 'UNIX') { + push @{$peers}, new Monitoring::Livestatus::UNIX(%peer_options); + } + elsif($peer->{'type'} eq 'INET') { + push @{$peers}, new Monitoring::Livestatus::INET(%peer_options); + } + } + $self->{'peers'} = $peers; + delete $self->{'socket'}; + delete $self->{'server'}; + } + + if(!defined $self->{'peers'}) { + croak('please specify at least one peer, socket or server'); + } + + # dont use threads with only one peer + if(scalar @{$self->{'peers'}} == 1) { $self->{'use_threads'} = 0; } + + # check for threads support + if(!defined $self->{'use_threads'}) { + $self->{'use_threads'} = 0; + if($Config{useithreads}) { + $self->{'use_threads'} = 1; + } + } + if($self->{'use_threads'}) { + eval { + require threads; + require Thread::Queue; + }; + if($@) { + $self->{'use_threads'} = 0; + $self->{'logger'}->debug('error initializing threads: '.$@) if defined $self->{'logger'}; + } else { + $self->_start_worker; + } + } + + # initialize peer keys + $self->{'peer_by_key'} = {}; + $self->{'peer_by_addr'} = {}; + for my $peer (@{$self->{'peers'}}) { + $self->{'peer_by_key'}->{$peer->peer_key} = $peer; + $self->{'peer_by_addr'}->{$peer->peer_addr} = $peer; + } + + $self->{'name'} = 'multiple connector' unless defined $self->{'name'}; + $self->{'logger'}->debug('initialized Monitoring::Livestatus::MULTI '.($self->{'use_threads'} ? 'with' : 'without' ).' threads') if $self->{'verbose'}; + + return $self; +} + + +######################################## + +=head1 METHODS + +=head2 do + +See L for more information. + +=cut + +sub do { + my $self = shift; + my $opts = $self->_lowercase_and_verify_options($_[1]); + my $t0 = [gettimeofday]; + + $self->_do_on_peers("do", $opts->{'backends'}, @_); + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for do('.$_[0].') in total') if $self->{'verbose'}; + return 1; +} + + +######################################## + +=head2 selectall_arrayref + +See L for more information. + +=cut + +sub selectall_arrayref { + my $self = shift; + my $opts = $self->_lowercase_and_verify_options($_[1]); + my $t0 = [gettimeofday]; + + $self->_log_statement($_[0], $opts, 0) if $self->{'verbose'}; + + my $return = $self->_merge_answer($self->_do_on_peers("selectall_arrayref", $opts->{'backends'}, @_)); + my $elapsed = tv_interval ( $t0 ); + if($self->{'verbose'}) { + my $total_results = 0; + $total_results = scalar @{$return} if defined $return; + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for selectall_arrayref() in total, results: '.$total_results); + } + + return $return; +} + + +######################################## + +=head2 selectall_hashref + +See L for more information. + +=cut + +sub selectall_hashref { + my $self = shift; + my $opts = $self->_lowercase_and_verify_options($_[2]); + my $t0 = [gettimeofday]; + + my $return = $self->_merge_answer($self->_do_on_peers("selectall_hashref", $opts->{'backends'}, @_)); + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for selectall_hashref() in total') if $self->{'verbose'}; + + return $return; +} + + +######################################## + +=head2 selectcol_arrayref + +See L for more information. + +=cut + +sub selectcol_arrayref { + my $self = shift; + my $opts = $self->_lowercase_and_verify_options($_[1]); + my $t0 = [gettimeofday]; + + my $return = $self->_merge_answer($self->_do_on_peers("selectcol_arrayref", $opts->{'backends'}, @_)); + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for selectcol_arrayref() in total') if $self->{'verbose'}; + + return $return; +} + + +######################################## + +=head2 selectrow_array + +See L for more information. + +=cut + +sub selectrow_array { + my $self = shift; + my $statement = $_[0]; + my $opts = $self->_lowercase_and_verify_options($_[1]); + my $t0 = [gettimeofday]; + my @return; + + if((defined $opts->{'sum'} and $opts->{'sum'} == 1) or (!defined $opts->{'sum'} and $statement =~ m/^Stats:/mx)) { + @return = @{$self->_sum_answer($self->_do_on_peers("selectrow_arrayref", $opts->{'backends'}, @_))}; + } else { + if($self->{'warnings'}) { + carp("selectrow_arrayref without Stats on multi backend will not work as expected!"); + } + my $rows = $self->_merge_answer($self->_do_on_peers("selectrow_arrayref", $opts->{'backends'}, @_)); + @return = @{$rows} if defined $rows; + } + + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for selectrow_array() in total') if $self->{'verbose'}; + + return @return; +} + + +######################################## + +=head2 selectrow_arrayref + +See L for more information. + +=cut + +sub selectrow_arrayref { + my $self = shift; + my $statement = $_[0]; + my $opts = $self->_lowercase_and_verify_options($_[1]); + my $t0 = [gettimeofday]; + my $return; + + if((defined $opts->{'sum'} and $opts->{'sum'} == 1) or (!defined $opts->{'sum'} and $statement =~ m/^Stats:/mx)) { + $return = $self->_sum_answer($self->_do_on_peers("selectrow_arrayref", $opts->{'backends'}, @_)); + } else { + if($self->{'warnings'}) { + carp("selectrow_arrayref without Stats on multi backend will not work as expected!"); + } + my $rows = $self->_merge_answer($self->_do_on_peers("selectrow_arrayref", $opts->{'backends'}, @_)); + $return = $rows->[0] if defined $rows->[0]; + } + + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for selectrow_arrayref() in total') if $self->{'verbose'}; + + return $return; +} + + +######################################## + +=head2 selectrow_hashref + +See L for more information. + +=cut + +sub selectrow_hashref { + my $self = shift; + my $statement = $_[0]; + my $opts = $self->_lowercase_and_verify_options($_[1]); + + my $t0 = [gettimeofday]; + + my $return; + + if((defined $opts->{'sum'} and $opts->{'sum'} == 1) or (!defined $opts->{'sum'} and $statement =~ m/^Stats:/mx)) { + $return = $self->_sum_answer($self->_do_on_peers("selectrow_hashref", $opts->{'backends'}, @_)); + } else { + if($self->{'warnings'}) { + carp("selectrow_hashref without Stats on multi backend will not work as expected!"); + } + $return = $self->_merge_answer($self->_do_on_peers("selectrow_hashref", $opts->{'backends'}, @_)); + } + + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for selectrow_hashref() in total') if $self->{'verbose'}; + + return $return; +} + + +######################################## + +=head2 selectscalar_value + +See L for more information. + +=cut + +sub selectscalar_value { + my $self = shift; + my $statement = $_[0]; + my $opts = $self->_lowercase_and_verify_options($_[1]); + + my $t0 = [gettimeofday]; + + my $return; + + if((defined $opts->{'sum'} and $opts->{'sum'} == 1) or (!defined $opts->{'sum'} and $statement =~ m/^Stats:/mx)) { + return $self->_sum_answer($self->_do_on_peers("selectscalar_value", $opts->{'backends'}, @_)); + } else { + if($self->{'warnings'}) { + carp("selectscalar_value without Stats on multi backend will not work as expected!"); + } + my $rows = $self->_merge_answer($self->_do_on_peers("selectscalar_value", $opts->{'backends'}, @_)); + + $return = $rows->[0] if defined $rows->[0]; + } + + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for selectscalar_value() in total') if $self->{'verbose'}; + + return $return; +} + + +######################################## + +=head2 errors_are_fatal + +See L for more information. + +=cut + +sub errors_are_fatal { + my $self = shift; + my $value = shift; + return $self->_change_setting('errors_are_fatal', $value); +} + + +######################################## + +=head2 warnings + +See L for more information. + +=cut + +sub warnings { + my $self = shift; + my $value = shift; + return $self->_change_setting('warnings', $value); +} + + +######################################## + +=head2 verbose + +See L for more information. + +=cut + +sub verbose { + my $self = shift; + my $value = shift; + return $self->_change_setting('verbose', $value); +} + + +######################################## + +=head2 peer_addr + +See L for more information. + +=cut + +sub peer_addr { + my $self = shift; + + my @addrs; + for my $peer (@{$self->{'peers'}}) { + push @addrs, $peer->peer_addr; + } + + return wantarray ? @addrs : undef; +} + + +######################################## + +=head2 peer_name + +See L for more information. + +=cut + +sub peer_name { + my $self = shift; + + my @names; + for my $peer (@{$self->{'peers'}}) { + push @names, $peer->peer_name; + } + + return wantarray ? @names : $self->{'name'}; +} + + +######################################## + +=head2 peer_key + +See L for more information. + +=cut + +sub peer_key { + my $self = shift; + + my @keys; + for my $peer (@{$self->{'peers'}}) { + push @keys, $peer->peer_key; + } + + return wantarray ? @keys : $self->{'key'}; +} + + +######################################## + +=head2 disable + + $ml->disable() + +disables this connection, returns the last state. + +=cut +sub disable { + my $self = shift; + my $peer_key = shift; + if(!defined $peer_key) { + for my $peer (@{$self->{'peers'}}) { + $peer->disable(); + } + return 1; + } else { + my $peer = $self->_get_peer_by_key($peer_key); + my $prev = $peer->{'disabled'}; + $peer->{'disabled'} = 1; + return $prev; + } +} + + +######################################## + +=head2 enable + + $ml->enable() + +enables this connection, returns the last state. + +=cut +sub enable { + my $self = shift; + my $peer_key = shift; + if(!defined $peer_key) { + for my $peer (@{$self->{'peers'}}) { + $peer->enable(); + } + return 1; + } else { + my $peer = $self->_get_peer_by_key($peer_key); + my $prev = $peer->{'disabled'}; + $peer->{'disabled'} = 0; + return $prev; + } +} + +######################################## +# INTERNAL SUBS +######################################## + +sub _change_setting { + my $self = shift; + my $key = shift; + my $value = shift; + my $old = $self->{$key}; + + # set new value + if(defined $value) { + $self->{$key} = $value; + for my $peer (@{$self->{'peers'}}) { + $peer->{$key} = $value; + } + + # restart workers + if($self->{'use_threads'}) { + _stop_worker(); + $self->_start_worker(); + } + } + + return $old; +} + + +######################################## +sub _start_worker { + my $self = shift; + + # create job transports + $self->{'WorkQueue'} = Thread::Queue->new; + $self->{'WorkResults'} = Thread::Queue->new; + + # set signal handler before thread is started + # otherwise they would be killed when started + # and stopped immediately after start + $SIG{'USR1'} = sub { threads->exit(); }; + + # start worker threads + our %threads; + my $threadcount = scalar @{$self->{'peers'}}; + for(my $x = 0; $x < $threadcount; $x++) { + $self->{'threads'}->[$x] = threads->new(\&_worker_thread, $self->{'peers'}, $self->{'WorkQueue'}, $self->{'WorkResults'}, $self->{'logger'}); + } + + # restore sig handler as it was only for the threads + $SIG{'USR1'} = 'DEFAULT'; + return; +} + + +######################################## +sub _stop_worker { + # try to kill our threads safely + eval { + for my $thr (threads->list()) { + $thr->kill('USR1')->detach(); + } + }; + return; +} + + +######################################## +sub _worker_thread { + local $SIG{'USR1'} = sub { threads->exit(); }; + + my $peers = shift; + my $workQueue = shift; + my $workResults = shift; + my $logger = shift; + + while (my $job = $workQueue->dequeue) { + my $erg; + eval { + $erg = _do_wrapper($peers->[$job->{'peer'}], $job->{'sub'}, $logger, @{$job->{'opts'}}); + }; + if($@) { + warn("Error in Thread ".$job->{'peer'}." :".$@); + $job->{'logger'}->error("Error in Thread ".$job->{'peer'}." :".$@) if defined $job->{'logger'}; + }; + $workResults->enqueue({ peer => $job->{'peer'}, result => $erg }); + } + return; +} + + +######################################## +sub _do_wrapper { + my $peer = shift; + my $sub = shift; + my $logger = shift; + my @opts = @_; + + my $t0 = [gettimeofday]; + + my $data = $peer->$sub(@opts); + + my $elapsed = tv_interval ( $t0 ); + $logger->debug(sprintf('%.4f', $elapsed).' sec for fetching data on '.$peer->peer_name.' ('.$peer->peer_addr.')') if defined $logger; + + $Monitoring::Livestatus::ErrorCode = 0 unless defined $Monitoring::Livestatus::ErrorCode; + $Monitoring::Livestatus::ErrorMessage = '' unless defined $Monitoring::Livestatus::ErrorMessage; + my $return = { + 'msg' => $Monitoring::Livestatus::ErrorMessage, + 'code' => $Monitoring::Livestatus::ErrorCode, + 'data' => $data, + }; + return $return; +} + + +######################################## +sub _do_on_peers { + my $self = shift; + my $sub = shift; + my $backends = shift; + my @opts = @_; + my $statement = $opts[0]; + my $use_threads = $self->{'use_threads'}; + my $t0 = [gettimeofday]; + + my $return; + my %codes; + my %messages; + my $query_options; + if($sub eq 'selectall_hashref') { + $query_options = $self->_lowercase_and_verify_options($opts[2]); + } else { + $query_options = $self->_lowercase_and_verify_options($opts[1]); + } + + # which peers affected? + my @peers; + if(defined $backends) { + my @backends; + if(ref $backends eq '') { + push @backends, $backends; + } + elsif(ref $backends eq 'ARRAY') { + @backends = @{$backends}; + } else { + croak("unsupported type for backend: ".ref($backends)); + } + + for my $key (@backends) { + my $backend = $self->_get_peer_by_key($key); + push @peers, $backend unless $backend->{'disabled'}; + } + } else { + # use all backends + @peers = @{$self->{'peers'}}; + } + + # its faster without threads for only one peer + if(scalar @peers <= 1) { $use_threads = 0; } + + # if we have limits set, we cannot use threads + if(defined $query_options->{'limit_start'}) { $use_threads = 0; } + + if($use_threads) { + # use the threaded variant + $self->{'logger'}->debug('using threads') if $self->{'verbose'}; + + my $peers_to_use; + for my $peer (@peers) { + if($peer->{'disabled'}) { + # dont send any query + } + elsif($peer->marked_bad) { + warn($peer->peer_name.' ('.$peer->peer_key.') is marked bad') if $self->{'verbose'}; + } + else { + $peers_to_use->{$peer->peer_key} = 1; + } + } + my $x = 0; + for my $peer (@{$self->{'peers'}}) { + if(defined $peers_to_use->{$peer->peer_key}) { + my $job = { + 'peer' => $x, + 'sub' => $sub, + 'opts' => \@opts, + }; + $self->{'WorkQueue'}->enqueue($job); + } + $x++; + } + + for(my $x = 0; $x < scalar keys %{$peers_to_use}; $x++) { + my $result = $self->{'WorkResults'}->dequeue; + my $peer = $self->{'peers'}->[$result->{'peer'}]; + if(defined $result->{'result'}) { + push @{$codes{$result->{'result'}->{'code'}}}, { 'peer' => $peer->peer_key, 'msg' => $result->{'result'}->{'msg'} }; + $return->{$peer->peer_key} = $result->{'result'}->{'data'}; + } else { + warn("undefined result for: $statement"); + } + } + } else { + $self->{'logger'}->debug('not using threads') if $self->{'verbose'}; + for my $peer (@peers) { + if($peer->{'disabled'}) { + # dont send any query + } + elsif($peer->marked_bad) { + warn($peer->peer_name.' ('.$peer->peer_key.') is marked bad') if $self->{'verbose'}; + } else { + my $erg = _do_wrapper($peer, $sub, $self->{'logger'}, @opts); + $return->{$peer->peer_key} = $erg->{'data'}; + push @{$codes{$erg->{'code'}}}, { 'peer' => $peer, 'msg' => $erg->{'msg'} }; + + # compute limits + if(defined $query_options->{'limit_length'} and $peer->{'meta_data'}->{'result_count'}) { + last; + } + # set a new start if we had rows already + if(defined $query_options->{'limit_start'}) { + $query_options->{'limit_start'} = $query_options->{'limit_start'} - $peer->{'meta_data'}->{'row_count'}; + } + } + } + } + + + # check if we different result stati + undef $Monitoring::Livestatus::ErrorMessage; + $Monitoring::Livestatus::ErrorCode = 0; + my @codes = sort keys %codes; + if(scalar @codes > 1) { + # got different results for our backends + if($self->{'verbose'}) { + $self->{'logger'}->warn("got different result stati: ".Dumper(\%codes)); + } + } else { + # got same result codes for all backend + } + + my $failed = 0; + my $code = $codes[0]; + if(defined $code and $code >= 300) { + $failed = 1; + } + + if($failed) { + my $msg = $codes{$code}->[0]->{'msg'}; + $self->{'logger'}->debug("same: $code -> $msg") if $self->{'verbose'}; + $Monitoring::Livestatus::ErrorMessage = $msg; + $Monitoring::Livestatus::ErrorCode = $code; + if($self->{'errors_are_fatal'}) { + croak("ERROR ".$code." - ".$Monitoring::Livestatus::ErrorMessage." in query:\n'".$statement."'\n"); + } + return; + } + + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for fetching all data') if $self->{'verbose'}; + + # deep copy result? + if($use_threads + and ( + (defined $query_options->{'deepcopy'} and $query_options->{'deepcopy'} == 1) + or + (defined $self->{'deepcopy'} and $self->{'deepcopy'} == 1) + ) + ) { + # result has to be cloned to avoid "Invalid value for shared scalar" error + + $return = $self->_clone($return, $self->{'logger'}); + } + + return($return); +} + + +######################################## +sub _merge_answer { + my $self = shift; + my $data = shift; + my $return; + + my $t0 = [gettimeofday]; + + # iterate over original peers to retain order + for my $peer (@{$self->{'peers'}}) { + my $key = $peer->peer_key; + next if !defined $data->{$key}; + + if(ref $data->{$key} eq 'ARRAY') { + $return = [] unless defined $return; + $return = [ @{$return}, @{$data->{$key}} ]; + } elsif(ref $data->{$key} eq 'HASH') { + $return = {} unless defined $return; + $return = { %{$return}, %{$data->{$key}} }; + } else { + push @{$return}, $data->{$key}; + } + } + + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for merging data') if $self->{'verbose'}; + + return($return); +} + + +######################################## +sub _sum_answer { + my $self = shift; + my $data = shift; + my $return; + my $t0 = [gettimeofday]; + for my $peername (keys %{$data}) { + if(ref $data->{$peername} eq 'HASH') { + for my $key (keys %{$data->{$peername}}) { + if(!defined $return->{$key}) { + $return->{$key} = $data->{$peername}->{$key}; + } elsif(looks_like_number($data->{$peername}->{$key})) { + $return->{$key} += $data->{$peername}->{$key}; + } + } + } + elsif(ref $data->{$peername} eq 'ARRAY') { + my $x = 0; + for my $val (@{$data->{$peername}}) { + if(!defined $return->[$x]) { + $return->[$x] = $data->{$peername}->[$x]; + } else { + $return->[$x] += $data->{$peername}->[$x]; + } + $x++; + } + } elsif(defined $data->{$peername}) { + $return = 0 unless defined $return; + next unless defined $data->{$peername}; + $return += $data->{$peername}; + } + } + + my $elapsed = tv_interval ( $t0 ); + $self->{'logger'}->debug(sprintf('%.4f', $elapsed).' sec for summarizing data') if $self->{'verbose'}; + + return $return; +} + + +######################################## +sub _clone { + my $self = shift; + my $data = shift; + my $logger = shift; + my $t0 = [gettimeofday]; + + my $return; + if(ref $data eq '') { + $return = $data; + } + elsif(ref $data eq 'ARRAY') { + $return = []; + for my $dat (@{$data}) { + push @{$return}, $self->_clone($dat); + } + } + elsif(ref $data eq 'HASH') { + $return = {}; + for my $key (keys %{$data}) { + $return->{$key} = $self->_clone($data->{$key}); + } + } + else { + croak("cant clone: ".(ref $data)); + } + + my $elapsed = tv_interval ( $t0 ); + $logger->debug(sprintf('%.4f', $elapsed).' sec for cloning data') if defined $logger; + + return $return; +} + + +######################################## +sub _get_peer_by_key { + my $self = shift; + my $key = shift; + + return unless defined $key; + return unless defined $self->{'peer_by_key'}->{$key}; + + return $self->{'peer_by_key'}->{$key}; +} + + +######################################## +sub _get_peer_by_addr { + my $self = shift; + my $addr = shift; + + return unless defined $addr; + return unless defined $self->{'peer_by_addr'}->{$addr}; + + return $self->{'peer_by_addr'}->{$addr}; +} + + +######################################## + +END { + # try to kill our threads safely + _stop_worker(); +} + +######################################## + +1; + +=head1 AUTHOR + +Sven Nierlein, Enierlein@cpan.orgE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2009 by Sven Nierlein + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__END__ diff --git a/api/perl/lib/Monitoring/Livestatus/UNIX.pm b/api/perl/lib/Monitoring/Livestatus/UNIX.pm new file mode 100644 index 0000000..63136ce --- /dev/null +++ b/api/perl/lib/Monitoring/Livestatus/UNIX.pm @@ -0,0 +1,112 @@ +package Monitoring::Livestatus::UNIX; + +use 5.000000; +use strict; +use warnings; +use IO::Socket::UNIX; +use Carp; +use base "Monitoring::Livestatus"; + +=head1 NAME + +Monitoring::Livestatus::UNIX - connector with unix sockets + +=head1 SYNOPSIS + + use Monitoring::Livestatus; + my $nl = Monitoring::Livestatus::UNIX->new( '/var/lib/livestatus/livestatus.sock' ); + my $hosts = $nl->selectall_arrayref("GET hosts"); + +=head1 CONSTRUCTOR + +=head2 new ( [ARGS] ) + +Creates an C object. C takes at least the socketpath. +Arguments are the same as in C. +If the constructor is only passed a single argument, it is assumed to +be a the C specification. Use either socker OR server. + +=cut + +sub new { + my $class = shift; + unshift(@_, "peer") if scalar @_ == 1; + my(%options) = @_; + $options{'name'} = $options{'peer'} unless defined $options{'name'}; + + $options{'backend'} = $class; + my $self = Monitoring::Livestatus->new(%options); + bless $self, $class; + confess('not a scalar') if ref $self->{'peer'} ne ''; + + return $self; +} + + +######################################## + +=head1 METHODS + +=cut + +sub _open { + my $self = shift; + + if(!-S $self->{'peer'}) { + my $msg = "failed to open socket $self->{'peer'}: $!"; + if($self->{'errors_are_fatal'}) { + croak($msg); + } + $Monitoring::Livestatus::ErrorCode = 500; + $Monitoring::Livestatus::ErrorMessage = $msg; + return; + } + my $sock = IO::Socket::UNIX->new( + Peer => $self->{'peer'}, + Type => SOCK_STREAM, + ); + if(!defined $sock or !$sock->connected()) { + my $msg = "failed to connect to $self->{'peer'} :$!"; + if($self->{'errors_are_fatal'}) { + croak($msg); + } + $Monitoring::Livestatus::ErrorCode = 500; + $Monitoring::Livestatus::ErrorMessage = $msg; + return; + } + + if(defined $self->{'query_timeout'}) { + # set timeout + $sock->timeout($self->{'query_timeout'}); + } + + return($sock); +} + + +######################################## + +sub _close { + my $self = shift; + my $sock = shift; + return unless defined $sock; + return close($sock); +} + + +1; + +=head1 AUTHOR + +Sven Nierlein, Enierlein@cpan.orgE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2009 by Sven Nierlein + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__END__ diff --git a/api/perl/t/01-Monitoring-Livestatus-basic_tests.t b/api/perl/t/01-Monitoring-Livestatus-basic_tests.t new file mode 100644 index 0000000..aeac3da --- /dev/null +++ b/api/perl/t/01-Monitoring-Livestatus-basic_tests.t @@ -0,0 +1,149 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More; +use File::Temp; +use Data::Dumper; +use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN ); +use_ok('Monitoring::Livestatus'); + +BEGIN { + if( $^O eq 'MSWin32' ) { + plan skip_all => 'no sockets on windows'; + } + else { + plan tests => 35; + } +} + +######################### +# get a temp file from File::Temp and replace it with our socket +my $fh = File::Temp->new(UNLINK => 0); +my $socket_path = $fh->filename; +unlink($socket_path); +my $listener = IO::Socket::UNIX->new( + Type => SOCK_STREAM, + Listen => SOMAXCONN, + Local => $socket_path, + ) or die("failed to open $socket_path as test socket: $!"); +######################### +# create object with single arg +my $ml = Monitoring::Livestatus->new( $socket_path ); +isa_ok($ml, 'Monitoring::Livestatus', 'single args'); +is($ml->peer_name(), $socket_path, 'get peer_name()'); +is($ml->peer_addr(), $socket_path, 'get peer_addr()'); + +######################### +# create object with hash args +my $line_seperator = 10; +my $column_seperator = 0; +$ml = Monitoring::Livestatus->new( + verbose => 0, + socket => $socket_path, + line_seperator => $line_seperator, + column_seperator => $column_seperator, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'new hash args'); +is($ml->peer_name(), $socket_path, 'get peer_name()'); +is($ml->peer_addr(), $socket_path, 'get peer_addr()'); + +######################### +# create object with peer arg +$ml = Monitoring::Livestatus->new( + peer => $socket_path, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg socket'); +is($ml->peer_name(), $socket_path, 'get peer_name()'); +is($ml->peer_addr(), $socket_path, 'get peer_addr()'); +isa_ok($ml->{'CONNECTOR'}, 'Monitoring::Livestatus::UNIX', 'peer backend UNIX'); + +######################### +# create object with peer arg +my $server = 'localhost:12345'; +$ml = Monitoring::Livestatus->new( + peer => $server, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg server'); +is($ml->peer_name(), $server, 'get peer_name()'); +is($ml->peer_addr(), $server, 'get peer_addr()'); +isa_ok($ml->{'CONNECTOR'}, 'Monitoring::Livestatus::INET', 'peer backend INET'); + +######################### +# create multi object with peers +$ml = Monitoring::Livestatus->new( + peer => [ $server, $socket_path ], + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg multi'); +my @names = $ml->peer_name(); +my @addrs = $ml->peer_addr(); +my $name = $ml->peer_name(); +my $expect = [ $server, $socket_path ]; +is_deeply(\@names, $expect, 'list context get peer_name()') or diag("got peer names: ".Dumper(\@names)."but expected: ".Dumper($expect)); +is($name, 'multiple connector', 'scalar context get peer_name()') or diag("got peer name: ".Dumper($name)."but expected: ".Dumper('multiple connector')); +is_deeply(\@addrs, $expect, 'list context get peer_addr()') or diag("got peer addrs: ".Dumper(\@addrs)."but expected: ".Dumper($expect)); + +######################### +# create multi object with peers and name +$ml = Monitoring::Livestatus->new( + peer => [ $server, $socket_path ], + name => 'test multi', + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg multi with name'); +$name = $ml->peer_name(); +is($name, 'test multi', 'peer_name()'); + +######################### +$ml = Monitoring::Livestatus->new( + peer => [ $socket_path ], + verbose => 0, + keepalive => 1, + logger => undef, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg multi with keepalive'); +is($ml->peer_name(), $socket_path, 'get peer_name()'); +is($ml->peer_addr(), $socket_path, 'get peer_addr()'); + +######################### +# timeout checks +$ml = Monitoring::Livestatus->new( + peer => [ $socket_path ], + verbose => 0, + timeout => 13, + logger => undef, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg multi with general timeout'); +is($ml->peer_name(), $socket_path, 'get peer_name()'); +is($ml->peer_addr(), $socket_path, 'get peer_addr()'); +is($ml->{'connect_timeout'}, 13, 'connect_timeout'); +is($ml->{'query_timeout'}, 13, 'query_timeout'); + +$ml = Monitoring::Livestatus->new( + peer => [ $socket_path ], + verbose => 0, + query_timeout => 14, + connect_timeout => 17, + logger => undef, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg multi with general timeout'); +is($ml->peer_name(), $socket_path, 'get peer_name()'); +is($ml->peer_addr(), $socket_path, 'get peer_addr()'); +is($ml->{'connect_timeout'}, 17, 'connect_timeout'); +is($ml->{'query_timeout'}, 14, 'query_timeout'); + + +######################### +# error retry +$ml = Monitoring::Livestatus->new( + peer => [ $socket_path ], + verbose => 0, + retries_on_connection_error => 3, + retry_interval => 1, + logger => undef, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'peer hash arg multi with error retry'); + +######################### +# cleanup +unlink($socket_path); diff --git a/api/perl/t/02-Monitoring-Livestatus-internals.t b/api/perl/t/02-Monitoring-Livestatus-internals.t new file mode 100644 index 0000000..addb3d2 --- /dev/null +++ b/api/perl/t/02-Monitoring-Livestatus-internals.t @@ -0,0 +1,148 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More; +use File::Temp; +use Data::Dumper; +use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN ); +use_ok('Monitoring::Livestatus'); + +BEGIN { + if( $^O eq 'MSWin32' ) { + plan skip_all => 'no sockets on windows'; + } + else { + plan tests => 14; + } +} + +######################### +# get a temp file from File::Temp and replace it with our socket +my $fh = File::Temp->new(UNLINK => 0); +my $socket_path = $fh->filename; +unlink($socket_path); +my $listener = IO::Socket::UNIX->new( + Type => SOCK_STREAM, + Listen => SOMAXCONN, + Local => $socket_path, + ) or die("failed to open $socket_path as test socket: $!"); + +######################### +# create object with single arg +my $ml = Monitoring::Livestatus->new( 'localhost:12345' ); +isa_ok($ml, 'Monitoring::Livestatus', 'single args server'); +isa_ok($ml->{'CONNECTOR'}, 'Monitoring::Livestatus::INET', 'single args server peer'); +is($ml->{'CONNECTOR'}->peer_name, 'localhost:12345', 'single args server peer name'); +is($ml->{'CONNECTOR'}->peer_addr, 'localhost:12345', 'single args server peer addr'); + +######################### +# create object with single arg +$ml = Monitoring::Livestatus->new( $socket_path ); +isa_ok($ml, 'Monitoring::Livestatus', 'single args socket'); +isa_ok($ml->{'CONNECTOR'}, 'Monitoring::Livestatus::UNIX', 'single args socket peer'); +is($ml->{'CONNECTOR'}->peer_name, $socket_path, 'single args socket peer name'); +is($ml->{'CONNECTOR'}->peer_addr, $socket_path, 'single args socket peer addr'); + +my $header = "404 43\n"; +my($error,$error_msg) = $ml->_parse_header($header); +is($error, '404', 'error code 404'); +isnt($error_msg, undef, 'error code 404 message'); + +######################### +my $stats_query1 = "GET services +Stats: state = 0 +Stats: state = 1 +Stats: state = 2 +Stats: state = 3 +Stats: state = 4 +Stats: host_state != 0 +Stats: state = 1 +StatsAnd: 2 +Stats: host_state != 0 +Stats: state = 2 +StatsAnd: 2 +Stats: host_state != 0 +Stats: state = 3 +StatsAnd: 2 +Stats: host_state != 0 +Stats: state = 3 +Stats: active_checks = 1 +StatsAnd: 3 +Stats: state = 3 +Stats: active_checks = 1 +StatsOr: 2"; +my @expected_keys1 = ( + 'state = 0', + 'state = 1', + 'state = 2', + 'state = 3', + 'state = 4', + 'host_state != 0 && state = 1', + 'host_state != 0 && state = 2', + 'host_state != 0 && state = 3', + 'host_state != 0 && state = 3 && active_checks = 1', + 'state = 3 || active_checks = 1', + ); +my @got_keys1 = @{$ml->_extract_keys_from_stats_statement($stats_query1)}; +is_deeply(\@got_keys1, \@expected_keys1, 'statsAnd, statsOr query keys') + or ( diag('got keys: '.Dumper(\@got_keys1)) ); + + +######################### +my $stats_query2 = "GET services +Stats: state = 0 as all_ok +Stats: state = 1 as all_warning +Stats: state = 2 as all_critical +Stats: state = 3 as all_unknown +Stats: state = 4 as all_pending +Stats: host_state != 0 +Stats: state = 1 +StatsAnd: 2 as all_warning_on_down_hosts +Stats: host_state != 0 +Stats: state = 2 +StatsAnd: 2 as all_critical_on_down_hosts +Stats: host_state != 0 +Stats: state = 3 +StatsAnd: 2 as all_unknown_on_down_hosts +Stats: host_state != 0 +Stats: state = 3 +Stats: active_checks_enabled = 1 +StatsAnd: 3 as all_unknown_active_on_down_hosts +Stats: state = 3 +Stats: active_checks_enabled = 1 +StatsOr: 2 as all_active_or_unknown"; +my @expected_keys2 = ( + 'all_ok', + 'all_warning', + 'all_critical', + 'all_unknown', + 'all_pending', + 'all_warning_on_down_hosts', + 'all_critical_on_down_hosts', + 'all_unknown_on_down_hosts', + 'all_unknown_active_on_down_hosts', + 'all_active_or_unknown', + ); +my @got_keys2 = @{$ml->_extract_keys_from_stats_statement($stats_query2)}; +is_deeply(\@got_keys2, \@expected_keys2, 'stats query keys2') + or ( diag('got keys: '.Dumper(\@got_keys2)) ); + + +######################### +my $normal_query1 = "GET services +Columns: host_name as host is_flapping description as name state +"; +my @expected_keys3 = ( + 'host', + 'is_flapping', + 'name', + 'state', + ); +my @got_keys3 = @{$ml->_extract_keys_from_columns_header($normal_query1)}; +is_deeply(\@got_keys3, \@expected_keys3, 'normal query keys') + or ( diag('got keys: '.Dumper(\@got_keys3)) ); + +######################### +unlink($socket_path); diff --git a/api/perl/t/03-Monitoring-Livestatus-MULTI-internals.t b/api/perl/t/03-Monitoring-Livestatus-MULTI-internals.t new file mode 100644 index 0000000..4cd3275 --- /dev/null +++ b/api/perl/t/03-Monitoring-Livestatus-MULTI-internals.t @@ -0,0 +1,215 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More; +use Data::Dumper; +use File::Temp; +use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN ); +use_ok('Monitoring::Livestatus::MULTI'); + +BEGIN { + if( $^O eq 'MSWin32' ) { + plan skip_all => 'no sockets on windows'; + } + else { + plan tests => 57; + } +} + +######################### +# create 2 test sockets +# get a temp file from File::Temp and replace it with our socket +my $fh = File::Temp->new(UNLINK => 0); +my $socket_path1 = $fh->filename; +unlink($socket_path1); +my $listener1 = IO::Socket::UNIX->new( + Type => SOCK_STREAM, + Listen => SOMAXCONN, + Local => $socket_path1, + ) or die("failed to open $socket_path1 as test socket: $!"); + +$fh = File::Temp->new(UNLINK => 0); +my $socket_path2 = $fh->filename; +unlink($socket_path2); +my $listener2 = IO::Socket::UNIX->new( + Type => SOCK_STREAM, + Listen => SOMAXCONN, + Local => $socket_path2, + ) or die("failed to open $socket_path2 as test socket: $!"); + +######################### +# test the _merge_answer +my $mergetests = [ + { # simple test for sliced selectall_arrayref + in => { '820e03551b95b42ec037c87aed9b8f4a' => [ { 'description' => 'test_flap_07', 'host_name' => 'test_host_000', 'state' => '0' }, { 'description' => 'test_flap_11', 'host_name' => 'test_host_000', 'state' => '0' } ], + '35bbb11a888f66131d429efd058fb141' => [ { 'description' => 'test_ok_00', 'host_name' => 'test_host_000', 'state' => '0' }, { 'description' => 'test_ok_01', 'host_name' => 'test_host_000', 'state' => '0' } ], + '70ea8fa14abb984761bdd45ef27685b0' => [ { 'description' => 'test_critical_00', 'host_name' => 'test_host_000', 'state' => '2' }, { 'description' => 'test_critical_19', 'host_name' => 'test_host_000', 'state' => '2' } ] + }, + exp => [ + { 'description' => 'test_flap_07', 'host_name' => 'test_host_000', 'state' => '0' }, + { 'description' => 'test_flap_11', 'host_name' => 'test_host_000', 'state' => '0' }, + { 'description' => 'test_ok_00', 'host_name' => 'test_host_000', 'state' => '0' }, + { 'description' => 'test_ok_01', 'host_name' => 'test_host_000', 'state' => '0' }, + { 'description' => 'test_critical_00', 'host_name' => 'test_host_000', 'state' => '2' }, + { 'description' => 'test_critical_19', 'host_name' => 'test_host_000', 'state' => '2' }, + ] + }, +]; + +######################### +# test object creation +my $ml = Monitoring::Livestatus::MULTI->new( [ $socket_path1, $socket_path2 ] ); +isa_ok($ml, 'Monitoring::Livestatus', 'single args sockets'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::UNIX', 'single args sockets peer'); +} + +$ml = Monitoring::Livestatus::MULTI->new( [$socket_path1] ); +isa_ok($ml, 'Monitoring::Livestatus', 'single array args socket'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::UNIX', 'single array args socket peer'); + is($peer->peer_addr, $socket_path1, 'single arrays args socket peer addr'); + is($peer->peer_name, $socket_path1, 'single arrays args socket peer name'); +} + +$ml = Monitoring::Livestatus::MULTI->new( 'localhost:5001' ); +isa_ok($ml, 'Monitoring::Livestatus', 'single args server'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::INET', 'single args server peer'); + like($peer->peer_addr, qr/^localhost/, 'single args servers peer addr'); + like($peer->peer_name, qr/^localhost/, 'single args servers peer name'); +} + +$ml = Monitoring::Livestatus::MULTI->new( ['localhost:5001'] ); +isa_ok($ml, 'Monitoring::Livestatus', 'single array args server'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::INET', 'single arrays args server peer'); + like($peer->peer_addr, qr/^localhost/, 'single arrays args servers peer addr'); + like($peer->peer_name, qr/^localhost/, 'single arrays args servers peer name'); +} + +$ml = Monitoring::Livestatus::MULTI->new( [ 'localhost:5001', 'localhost:5002' ] ); +isa_ok($ml, 'Monitoring::Livestatus', 'single args servers'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::INET', 'single args servers peer'); + like($peer->peer_addr, qr/^localhost/, 'single args servers peer addr'); + like($peer->peer_name, qr/^localhost/, 'single args servers peer name'); +} + +$ml = Monitoring::Livestatus::MULTI->new( peer => [ 'localhost:5001', 'localhost:5002' ] ); +isa_ok($ml, 'Monitoring::Livestatus', 'hash args servers'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::INET', 'hash args servers peer'); + like($peer->peer_addr, qr/^localhost/, 'hash args servers peer addr'); + like($peer->peer_name, qr/^localhost/, 'hash args servers peer name'); +} + +$ml = Monitoring::Livestatus::MULTI->new( peer => [ $socket_path1, $socket_path2 ] ); +isa_ok($ml, 'Monitoring::Livestatus', 'hash args sockets'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::UNIX', 'hash args sockets peer'); +} + +$ml = Monitoring::Livestatus::MULTI->new( peer => { $socket_path1 => 'Location 1', $socket_path2 => 'Location2' } ); +isa_ok($ml, 'Monitoring::Livestatus', 'hash args hashed sockets'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::UNIX', 'hash args hashed sockets peer'); + like($peer->peer_name, qr/^Location/, 'hash args hashed sockets peer name'); +} + +$ml = Monitoring::Livestatus::MULTI->new( peer => { 'localhost:5001' => 'Location 1', 'localhost:5002' => 'Location2' } ); +isa_ok($ml, 'Monitoring::Livestatus', 'hash args hashed servers'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::INET', 'hash args hashed servers peer'); + like($peer->peer_addr, qr/^localhost/, 'hash args hashed servers peer addr'); + like($peer->peer_name, qr/^Location/, 'hash args hashed servers peer name'); +} + +$ml = Monitoring::Livestatus::MULTI->new( $socket_path1 ); +isa_ok($ml, 'Monitoring::Livestatus', 'single args socket'); +for my $peer (@{$ml->{'peers'}}) { + isa_ok($peer, 'Monitoring::Livestatus::UNIX', 'single args socket peer'); +} + +######################### +# test internal subs +$ml = Monitoring::Livestatus::MULTI->new('peer' => ['192.168.123.2:9996', '192.168.123.2:9997', '192.168.123.2:9998' ] ); + +my $x = 0; +for my $test (@{$mergetests}) { + my $got = $ml->_merge_answer($test->{'in'}); + is_deeply($got, $test->{'exp'}, '_merge_answer test '.$x) + or diag("got: ".Dumper($got)."\nbut expected ".Dumper($test->{'exp'})); + $x++; +} + +######################### +# test the _sum_answer +my $sumtests = [ + { # hashes + in => { '192.168.123.2:9996' => { 'ok' => '12', 'warning' => '8' }, + '192.168.123.2:9997' => { 'ok' => '17', 'warning' => '7' }, + '192.168.123.2:9998' => { 'ok' => '13', 'warning' => '2' } + }, + exp => { 'ok' => '42', 'warning' => '17' } + }, + { # hashes, undefs + in => { '192.168.123.2:9996' => { 'ok' => '12', 'warning' => '8' }, + '192.168.123.2:9997' => undef, + '192.168.123.2:9998' => { 'ok' => '13', 'warning' => '2' } + }, + exp => { 'ok' => '25', 'warning' => '10' } + }, + { # hashes, undefs + in => { '192.168.123.2:9996' => { 'ok' => '12', 'warning' => '8' }, + '192.168.123.2:9997' => {}, + '192.168.123.2:9998' => { 'ok' => '13', 'warning' => '2' } + }, + exp => { 'ok' => '25', 'warning' => '10' } + }, + { # arrays + in => { '192.168.123.2:9996' => [ '3302', '235' ], + '192.168.123.2:9997' => [ '3324', '236' ], + '192.168.123.2:9998' => [ '3274', '236' ] + }, + exp => [ 9900, 707 ] + }, + { # undefs / scalars + in => { 'e69322abf0352888e598da3e2514df4a' => undef, + 'f42530d7e8c2b52732ba427b1e5e0a8e' => '1' + }, + exp => 1, + }, + { # arrays, undefs + in => { '192.168.123.2:9996' => [ '2', '5' ], + '192.168.123.2:9997' => [ ], + '192.168.123.2:9998' => [ '4', '6' ] + }, + exp => [ 6, 11 ] + }, + { # arrays, undefs + in => { '192.168.123.2:9996' => [ '2', '5' ], + '192.168.123.2:9997' => undef, + '192.168.123.2:9998' => [ '4', '6' ] + }, + exp => [ 6, 11 ] + }, +]; + +$x = 1; +for my $test (@{$sumtests}) { + my $got = $ml->_sum_answer($test->{'in'}); + is_deeply($got, $test->{'exp'}, '_sum_answer test '.$x) + or diag("got: ".Dumper($got)."\nbut expected ".Dumper($test->{'exp'})); + $x++; +} + +######################### +# clone test +my $clone = $ml->_clone($mergetests); +is_deeply($clone, $mergetests, 'merge test clone'); + +$clone = $ml->_clone($sumtests); +is_deeply($clone, $sumtests, 'sum test clone'); diff --git a/api/perl/t/20-Monitoring-Livestatus-test_socket.t b/api/perl/t/20-Monitoring-Livestatus-test_socket.t new file mode 100644 index 0000000..3c6380b --- /dev/null +++ b/api/perl/t/20-Monitoring-Livestatus-test_socket.t @@ -0,0 +1,329 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More; +use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN ); +use Data::Dumper; +use JSON::XS; + +BEGIN { + eval {require threads;}; + if ( $@ ) { + plan skip_all => 'need threads support for testing a real socket' + } + elsif( $^O eq 'MSWin32' ) { + plan skip_all => 'no sockets on windows'; + } + else{ + plan tests => 109 + } +} + +use File::Temp; +BEGIN { use_ok('Monitoring::Livestatus') }; + +######################### +# Normal Querys +######################### +my $line_seperator = 10; +my $column_seperator = 0; +my $test_data = [ ["alias","name","contacts"], # table header + ["alias1","host1","contact1"], # row 1 + ["alias2","host2","contact2"], # row 2 + ["alias3","host3","contact3"], # row 3 + ]; +my $test_hostgroups = [['']]; # test one row with no data + +# expected results +my $selectall_arrayref1 = [ [ 'alias1', 'host1', 'contact1' ], + [ 'alias2', 'host2', 'contact2' ], + [ 'alias3', 'host3', 'contact3' ] + ]; +my $selectall_arrayref2 = [ + { 'contacts' => 'contact1', 'name' => 'host1', 'alias' => 'alias1' }, + { 'contacts' => 'contact2', 'name' => 'host2', 'alias' => 'alias2' }, + { 'contacts' => 'contact3', 'name' => 'host3', 'alias' => 'alias3' } + ]; +my $selectall_hashref = { + 'host1' => { 'contacts' => 'contact1', 'name' => 'host1', 'alias' => 'alias1' }, + 'host2' => { 'contacts' => 'contact2', 'name' => 'host2', 'alias' => 'alias2' }, + 'host3' => { 'contacts' => 'contact3', 'name' => 'host3', 'alias' => 'alias3' } + }; +my $selectcol_arrayref1 = [ 'alias1', 'alias2', 'alias3' ]; +my $selectcol_arrayref2 = [ 'alias1', 'host1', 'alias2', 'host2', 'alias3', 'host3' ]; +my $selectcol_arrayref3 = [ 'alias1', 'host1', 'contact1', 'alias2', 'host2', 'contact2', 'alias3', 'host3', 'contact3' ]; +my @selectrow_array = ( 'alias1', 'host1', 'contact1' ); +my $selectrow_arrayref = [ 'alias1', 'host1', 'contact1' ]; +my $selectrow_hashref = { 'contacts' => 'contact1', 'name' => 'host1', 'alias' => 'alias1' }; + +######################### +# Single Querys +######################### +my $single_statement = "GET hosts\nColumns: alias\nFilter: name = host1"; +my $selectscalar_value = 'alias1'; + +######################### +# Stats Querys +######################### +my $stats_statement = "GET services\nStats: state = 0\nStats: state = 1\nStats: state = 2\nStats: state = 3"; +my $stats_data = [[4297,13,9,0]]; + +# expected results +my $stats_selectall_arrayref1 = [ [4297,13,9,0] ]; +my $stats_selectall_arrayref2 = [ { 'state = 0' => '4297', 'state = 1' => '13', 'state = 2' => '9', 'state = 3' => 0 } ]; +my $stats_selectcol_arrayref = [ '4297' ]; +my @stats_selectrow_array = ( '4297', '13', '9', '0' ); +my $stats_selectrow_arrayref = [ '4297', '13', '9', '0' ]; +my $stats_selectrow_hashref = { 'state = 0' => '4297', 'state = 1' => '13', 'state = 2' => '9', 'state = 3' => 0 }; + +######################### +# Empty Querys +######################### +my $empty_statement = "GET services\nFilter: description = empty"; + +# expected results +my $empty_selectall_arrayref = []; +my $empty_selectcol_arrayref = []; +my @empty_selectrow_array; +my $empty_selectrow_arrayref; +my $empty_selectrow_hashref; + + +######################### +# get a temp file from File::Temp and replace it with our socket +my $fh = File::Temp->new(UNLINK => 0); +my $socket_path = $fh->filename; +unlink($socket_path); +my $thr1 = threads->create('create_socket', 'unix'); +######################### +# get a temp file from File::Temp and replace it with our socket +my $server = 'localhost:32987'; +my $thr2 = threads->create('create_socket', 'inet'); +sleep(1); + +######################### +my $objects_to_test = { + # create unix object with hash args + 'unix_hash_args' => Monitoring::Livestatus->new( + verbose => 0, + socket => $socket_path, + line_seperator => $line_seperator, + column_seperator => $column_seperator, + ), + + # create unix object with a single arg + 'unix_single_arg' => Monitoring::Livestatus::UNIX->new( $socket_path ), + + # create inet object with hash args + 'inet_hash_args' => Monitoring::Livestatus->new( + verbose => 0, + server => $server, + line_seperator => $line_seperator, + column_seperator => $column_seperator, + ), + + # create inet object with a single arg + 'inet_single_arg' => Monitoring::Livestatus::INET->new( $server ), + +}; + +for my $key (keys %{$objects_to_test}) { + my $ml = $objects_to_test->{$key}; + isa_ok($ml, 'Monitoring::Livestatus'); + + # we dont need warnings for testing + $ml->warnings(0); + + ################################################## + # test settings + my $rt = $ml->verbose(1); + is($rt, '0', 'enable verbose'); + $rt = $ml->verbose(0); + is($rt, '1', 'disable verbose'); + + $rt = $ml->errors_are_fatal(0); + is($rt, '1', 'disable errors_are_fatal'); + $rt = $ml->errors_are_fatal(1); + is($rt, '0', 'enable errors_are_fatal'); + + ################################################## + # do some sample querys + my $statement = "GET hosts"; + + ######################### + my $ary_ref = $ml->selectall_arrayref($statement); + is_deeply($ary_ref, $selectall_arrayref1, 'selectall_arrayref($statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectall_arrayref1)); + + ######################### + $ary_ref = $ml->selectall_arrayref($statement, { Slice => {} }); + is_deeply($ary_ref, $selectall_arrayref2, 'selectall_arrayref($statement, { Slice => {} })') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectall_arrayref2)); + + ######################### + my $hash_ref = $ml->selectall_hashref($statement, 'name'); + is_deeply($hash_ref, $selectall_hashref, 'selectall_hashref($statement, "name")') + or diag("got: ".Dumper($hash_ref)."\nbut expected ".Dumper($selectall_hashref)); + + ######################### + $ary_ref = $ml->selectcol_arrayref($statement); + is_deeply($ary_ref, $selectcol_arrayref1, 'selectcol_arrayref($statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectcol_arrayref1)); + + ######################### + $ary_ref = $ml->selectcol_arrayref($statement, { Columns=>[1,2] }); + is_deeply($ary_ref, $selectcol_arrayref2, 'selectcol_arrayref($statement, { Columns=>[1,2] })') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectcol_arrayref2)); + + $ary_ref = $ml->selectcol_arrayref($statement, { Columns=>[1,2,3] }); + is_deeply($ary_ref, $selectcol_arrayref3, 'selectcol_arrayref($statement, { Columns=>[1,2,3] })') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectcol_arrayref3)); + + ######################### + my @row_ary = $ml->selectrow_array($statement); + is_deeply(\@row_ary, \@selectrow_array, 'selectrow_array($statement)') + or diag("got: ".Dumper(\@row_ary)."\nbut expected ".Dumper(\@selectrow_array)); + + ######################### + $ary_ref = $ml->selectrow_arrayref($statement); + is_deeply($ary_ref, $selectrow_arrayref, 'selectrow_arrayref($statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectrow_arrayref)); + + ######################### + $hash_ref = $ml->selectrow_hashref($statement); + is_deeply($hash_ref, $selectrow_hashref, 'selectrow_hashref($statement)') + or diag("got: ".Dumper($hash_ref)."\nbut expected ".Dumper($selectrow_hashref)); + + ################################################## + # stats querys + ################################################## + $ary_ref = $ml->selectall_arrayref($stats_statement); + is_deeply($ary_ref, $stats_selectall_arrayref1, 'selectall_arrayref($stats_statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($stats_selectall_arrayref1)); + + $ary_ref = $ml->selectall_arrayref($stats_statement, { Slice => {} }); + is_deeply($ary_ref, $stats_selectall_arrayref2, 'selectall_arrayref($stats_statement, { Slice => {} })') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($stats_selectall_arrayref2)); + + $ary_ref = $ml->selectcol_arrayref($stats_statement); + is_deeply($ary_ref, $stats_selectcol_arrayref, 'selectcol_arrayref($stats_statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($stats_selectcol_arrayref)); + + @row_ary = $ml->selectrow_array($stats_statement); + is_deeply(\@row_ary, \@stats_selectrow_array, 'selectrow_arrayref($stats_statement)') + or diag("got: ".Dumper(\@row_ary)."\nbut expected ".Dumper(\@stats_selectrow_array)); + + $ary_ref = $ml->selectrow_arrayref($stats_statement); + is_deeply($ary_ref, $stats_selectrow_arrayref, 'selectrow_arrayref($stats_statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($stats_selectrow_arrayref)); + + $hash_ref = $ml->selectrow_hashref($stats_statement); + is_deeply($hash_ref, $stats_selectrow_hashref, 'selectrow_hashref($stats_statement)') + or diag("got: ".Dumper($hash_ref)."\nbut expected ".Dumper($stats_selectrow_hashref)); + + my $scal = $ml->selectscalar_value($single_statement); + is($scal, $selectscalar_value, 'selectscalar_value($single_statement)') + or diag("got: ".Dumper($scal)."\nbut expected ".Dumper($selectscalar_value)); + + ################################################## + # empty querys + ################################################## + $ary_ref = $ml->selectall_arrayref($empty_statement); + is_deeply($ary_ref, $empty_selectall_arrayref, 'selectall_arrayref($empty_statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($empty_selectall_arrayref)); + + $ary_ref = $ml->selectcol_arrayref($empty_statement); + is_deeply($ary_ref, $empty_selectcol_arrayref, 'selectcol_arrayref($empty_statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($empty_selectcol_arrayref)); + + @row_ary = $ml->selectrow_array($empty_statement); + is_deeply(\@row_ary, \@empty_selectrow_array, 'selectrow_arrayref($empty_statement)') + or diag("got: ".Dumper(\@row_ary)."\nbut expected ".Dumper(\@empty_selectrow_array)); + + $ary_ref = $ml->selectrow_arrayref($empty_statement); + is_deeply($ary_ref, $empty_selectrow_arrayref, 'selectrow_arrayref($empty_statement)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($empty_selectrow_arrayref)); + + $hash_ref = $ml->selectrow_hashref($empty_statement); + is_deeply($hash_ref, $empty_selectrow_hashref, 'selectrow_hashref($empty_statement)') + or diag("got: ".Dumper($hash_ref)."\nbut expected ".Dumper($empty_selectrow_hashref)); + + ################################################## + # empty rows and columns + ################################################## + my $empty_hostgroups_stm = "GET hostgroups\nColumns: members"; + $ary_ref = $ml->selectall_arrayref($empty_hostgroups_stm); + is_deeply($ary_ref, $test_hostgroups, 'selectall_arrayref($empty_hostgroups_stm)') + or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($test_hostgroups)); + +} + +################################################## +# exit threads +$thr1->kill('KILL')->detach(); +$thr2->kill('KILL')->detach(); +exit; + + +######################### +# SUBS +######################### +# test socket server +sub create_socket { + my $type = shift; + my $listener; + + $SIG{'KILL'} = sub { threads->exit(); }; + + if($type eq 'unix') { + print "creating unix socket\n"; + $listener = IO::Socket::UNIX->new( + Type => SOCK_STREAM, + Listen => SOMAXCONN, + Local => $socket_path, + ) or die("failed to open $socket_path as test socket: $!"); + } + elsif($type eq 'inet') { + print "creating tcp socket\n"; + $listener = IO::Socket::INET->new( + LocalAddr => $server, + Proto => 'tcp', + Listen => 1, + Reuse => 1, + ) or die("failed to listen on $server: $!"); + } else { + die("unknown type"); + } + while( my $socket = $listener->accept() or die('cannot accept: $!') ) { + my $recv = ""; + while(<$socket>) { $recv .= $_; last if $_ eq "\n" } + my $data; + my $status = 200; + if($recv =~ m/^GET .*?\s+Filter:.*?empty/m) { + $data = ''; + } + elsif($recv =~ m/^GET hosts\s+Columns: alias/m) { + my @data = @{$test_data}[1..3]; + $data = encode_json(\@data)."\n"; + } + elsif($recv =~ m/^GET hosts\s+Columns: name/m) { + $data = encode_json(\@{$test_data}[1..3])."\n"; + } + elsif($recv =~ m/^GET hosts/) { + $data = encode_json($test_data)."\n"; + } + elsif($recv =~ m/^GET hostgroups/) { + $data = encode_json(\@{$test_hostgroups})."\n"; + } + elsif($recv =~ m/^GET services/ and $recv =~ m/Stats:/m) { + $data = encode_json(\@{$stats_data})."\n"; + } + my $content_length = sprintf("%11s", length($data)); + print $socket $status." ".$content_length."\n"; + print $socket $data; + close($socket); + } + unlink($socket_path); +} diff --git a/api/perl/t/21-Monitoring-Livestatus-INET.t b/api/perl/t/21-Monitoring-Livestatus-INET.t new file mode 100644 index 0000000..1ecc8b0 --- /dev/null +++ b/api/perl/t/21-Monitoring-Livestatus-INET.t @@ -0,0 +1,30 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More tests => 3; +use IO::Socket::INET; +BEGIN { use_ok('Monitoring::Livestatus::INET') }; + +######################### +# create a tmp listener +my $server = 'localhost:9999'; +my $listener = IO::Socket::INET->new( + ) or die("failed to open port as test listener: $!"); +######################### +# create object with single arg +my $ml = Monitoring::Livestatus::INET->new( $server ); +isa_ok($ml, 'Monitoring::Livestatus', 'Monitoring::Livestatus::INET->new()'); + +######################### +# create object with hash args +my $line_seperator = 10; +my $column_seperator = 0; +$ml = Monitoring::Livestatus::INET->new( + verbose => 0, + server => $server, + line_seperator => $line_seperator, + column_seperator => $column_seperator, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'Monitoring::Livestatus::INET->new(%args)'); diff --git a/api/perl/t/22-Monitoring-Livestatus-UNIX.t b/api/perl/t/22-Monitoring-Livestatus-UNIX.t new file mode 100644 index 0000000..4b17813 --- /dev/null +++ b/api/perl/t/22-Monitoring-Livestatus-UNIX.t @@ -0,0 +1,26 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More tests => 3; +use IO::Socket::INET; +BEGIN { use_ok('Monitoring::Livestatus::UNIX') }; + +######################### +# create object with single arg +my $socket = "/tmp/blah.socket"; +my $ml = Monitoring::Livestatus::UNIX->new( $socket ); +isa_ok($ml, 'Monitoring::Livestatus', 'Monitoring::Livestatus::UNIX->new()'); + +######################### +# create object with hash args +my $line_seperator = 10; +my $column_seperator = 0; +$ml = Monitoring::Livestatus::UNIX->new( + verbose => 0, + socket => $socket, + line_seperator => $line_seperator, + column_seperator => $column_seperator, + ); +isa_ok($ml, 'Monitoring::Livestatus', 'Monitoring::Livestatus::UNIX->new(%args)'); diff --git a/api/perl/t/30-Monitoring-Livestatus-live-test.t b/api/perl/t/30-Monitoring-Livestatus-live-test.t new file mode 100644 index 0000000..6a82d36 --- /dev/null +++ b/api/perl/t/30-Monitoring-Livestatus-live-test.t @@ -0,0 +1,472 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More; +use Data::Dumper; + +if ( ! defined $ENV{TEST_SOCKET} or !defined $ENV{TEST_SERVER} ) { + my $msg = 'Author test. Set $ENV{TEST_SOCKET} and $ENV{TEST_SERVER} to run'; + plan( skip_all => $msg ); +} else { + plan( tests => 727 ); +} + +# set an alarm +my $lastquery; +$SIG{ALRM} = sub { + my @caller = caller; + print STDERR 'last query: '.$lastquery if defined $lastquery; + die "timeout reached:".Dumper(\@caller)."\n" +}; +alarm(120); + +use_ok('Monitoring::Livestatus'); + +######################### +my $line_seperator = 10; +my $column_seperator = 0; +my $objects_to_test = { + # UNIX + # create unix object with a single arg +# '01 unix_single_arg' => Monitoring::Livestatus::UNIX->new( $ENV{TEST_SOCKET} ), + + # create unix object with hash args + '02 unix_few_args' => Monitoring::Livestatus->new( + #verbose => 1, + socket => $ENV{TEST_SOCKET}, + line_seperator => $line_seperator, + column_seperator => $column_seperator, + ), + + # create unix object with hash args + '03 unix_keepalive' => Monitoring::Livestatus->new( + verbose => 0, + socket => $ENV{TEST_SOCKET}, + keepalive => 1, + ), + + # TCP + # create inet object with a single arg + '04 inet_single_arg' => Monitoring::Livestatus::INET->new( $ENV{TEST_SERVER} ), + + # create inet object with hash args + '05 inet_few_args' => Monitoring::Livestatus->new( + verbose => 0, + server => $ENV{TEST_SERVER}, + line_seperator => $line_seperator, + column_seperator => $column_seperator, + ), + + + # create inet object with keepalive + '06 inet_keepalive' => Monitoring::Livestatus->new( + verbose => 0, + server => $ENV{TEST_SERVER}, + keepalive => 1, + ), + + # create multi single args + '07 multi_keepalive' => Monitoring::Livestatus->new( [ $ENV{TEST_SERVER}, $ENV{TEST_SOCKET} ] ), + + # create multi object with keepalive + '08 multi_keepalive_hash_args' => Monitoring::Livestatus->new( + verbose => 0, + peer => [ $ENV{TEST_SERVER}, $ENV{TEST_SOCKET} ], + keepalive => 1, + ), + + # create multi object without keepalive + '09 multi_no_keepalive' => Monitoring::Livestatus->new( + peer => [ $ENV{TEST_SERVER}, $ENV{TEST_SOCKET} ], + keepalive => 0, + ), + + # create multi object without threads + '10 multi_no_threads' => Monitoring::Livestatus->new( + peer => [ $ENV{TEST_SERVER}, $ENV{TEST_SOCKET} ], + use_threads => 0, + ), + + # create multi object with only one peer + '11 multi_one_peer' => Monitoring::Livestatus::MULTI->new( + peer => $ENV{TEST_SERVER}, + ), + + # create multi object without threads + '12 multi_two_peers' => Monitoring::Livestatus::MULTI->new( + peer => [ $ENV{TEST_SERVER}, $ENV{TEST_SOCKET} ], + ), +}; + +my $expected_keys = { + 'columns' => [ + 'description','name','table','type' + ], + 'commands' => [ + 'line','name' + ], + 'comments' => [ + '__all_from_hosts__', '__all_from_services__', + 'author','comment','entry_time','entry_type','expire_time','expires', 'id','persistent', + 'source','type' + ], + 'contacts' => [ + 'address1','address2','address3','address4','address5','address6','alias', + 'can_submit_commands','custom_variable_names','custom_variable_values','email', + 'host_notification_period','host_notifications_enabled','in_host_notification_period', + 'in_service_notification_period','name','modified_attributes','modified_attributes_list', + 'pager','service_notification_period','service_notifications_enabled' + ], + 'contactgroups' => [ 'name', 'alias', 'members' ], + 'downtimes' => [ + '__all_from_hosts__', '__all_from_services__', + 'author','comment','duration','end_time','entry_time','fixed','id','start_time', + 'triggered_by','type' + ], + 'hostgroups' => [ + 'action_url','alias','members','name','members_with_state','notes','notes_url','num_hosts','num_hosts_down', + 'num_hosts_pending','num_hosts_unreach','num_hosts_up','num_services','num_services_crit', + 'num_services_hard_crit','num_services_hard_ok','num_services_hard_unknown', + 'num_services_hard_warn','num_services_ok','num_services_pending','num_services_unknown', + 'num_services_warn','worst_host_state','worst_service_hard_state','worst_service_state' + ], + 'hosts' => [ + 'accept_passive_checks','acknowledged','acknowledgement_type','action_url','action_url_expanded', + 'active_checks_enabled','address','alias','check_command','check_freshness','check_interval', + 'check_options','check_period','check_type','checks_enabled','childs','comments','comments_with_info', + 'contacts','current_attempt','current_notification_number','custom_variable_names', + 'custom_variable_values','display_name','downtimes','downtimes_with_info','event_handler_enabled', + 'execution_time','first_notification_delay','flap_detection_enabled','groups','hard_state','has_been_checked', + 'high_flap_threshold','icon_image','icon_image_alt','icon_image_expanded','in_check_period', + 'in_notification_period','initial_state','is_executing','is_flapping','last_check','last_hard_state', + 'last_hard_state_change','last_notification','last_state','last_state_change','latency','last_time_down', + 'last_time_unreachable','last_time_up','long_plugin_output','low_flap_threshold','max_check_attempts','name', + 'modified_attributes','modified_attributes_list','next_check', + 'next_notification','notes','notes_expanded','notes_url','notes_url_expanded','notification_interval', + 'notification_period','notifications_enabled','num_services','num_services_crit','num_services_hard_crit', + 'num_services_hard_ok','num_services_hard_unknown','num_services_hard_warn','num_services_ok', + 'num_services_pending','num_services_unknown','num_services_warn','obsess_over_host','parents', + 'pending_flex_downtime','percent_state_change','perf_data','plugin_output', + 'process_performance_data','retry_interval','scheduled_downtime_depth','services','services_with_state', + 'state','state_type','statusmap_image','total_services','worst_service_hard_state','worst_service_state', + 'x_3d','y_3d','z_3d' + ], + 'hostsbygroup' => [ + '__all_from_hosts__', '__all_from_hostgroups__' + ], + 'log' => [ + '__all_from_hosts__','__all_from_services__','__all_from_contacts__','__all_from_commands__', + 'attempt','class','command_name','comment','contact_name','host_name','lineno','message','options', + 'plugin_output','service_description','state','state_type','time','type' + ], + 'servicegroups' => [ + 'action_url','alias','members','name','members_with_state','notes','notes_url','num_services','num_services_crit', + 'num_services_hard_crit','num_services_hard_ok','num_services_hard_unknown', + 'num_services_hard_warn','num_services_ok','num_services_pending','num_services_unknown', + 'num_services_warn','worst_service_state' + ], + 'servicesbygroup' => [ + '__all_from_services__', '__all_from_hosts__', '__all_from_servicegroups__' + ], + 'services' => [ + '__all_from_hosts__', + 'accept_passive_checks','acknowledged','acknowledgement_type','action_url','action_url_expanded', + 'active_checks_enabled','check_command','check_interval','check_options','check_period', + 'check_type','checks_enabled','comments','comments_with_info','contacts','current_attempt', + 'current_notification_number','custom_variable_names','custom_variable_values', + 'description','display_name','downtimes','downtimes_with_info','event_handler','event_handler_enabled', + 'execution_time','first_notification_delay','flap_detection_enabled','groups', + 'has_been_checked','high_flap_threshold','icon_image','icon_image_alt','icon_image_expanded','in_check_period', + 'in_notification_period','initial_state','is_executing','is_flapping','last_check', + 'last_hard_state','last_hard_state_change','last_notification','last_state', + 'last_state_change','latency','last_time_critical','last_time_ok','last_time_unknown','last_time_warning', + 'long_plugin_output','low_flap_threshold','max_check_attempts','modified_attributes','modified_attributes_list', + 'next_check','next_notification','notes','notes_expanded','notes_url','notes_url_expanded', + 'notification_interval','notification_period','notifications_enabled','obsess_over_service', + 'percent_state_change','perf_data','plugin_output','process_performance_data','retry_interval', + 'scheduled_downtime_depth','state','state_type' + ], + 'servicesbyhostgroup' => [ + '__all_from_services__', '__all_from_hosts__', '__all_from_hostgroups__' + ], + 'status' => [ + 'accept_passive_host_checks','accept_passive_service_checks','cached_log_messages', + 'check_external_commands','check_host_freshness','check_service_freshness','connections', + 'connections_rate','enable_event_handlers','enable_flap_detection','enable_notifications', + 'execute_host_checks','execute_service_checks','forks','forks_rate','host_checks','host_checks_rate','interval_length', + 'last_command_check','last_log_rotation','livestatus_version','log_messages','log_messages_rate','nagios_pid','neb_callbacks', + 'neb_callbacks_rate','obsess_over_hosts','obsess_over_services','process_performance_data', + 'program_start','program_version','requests','requests_rate','service_checks','service_checks_rate' + ], + 'timeperiods' => [ 'in', 'name', 'alias' ], +}; + +my $author = 'Monitoring::Livestatus test'; +for my $key (sort keys %{$objects_to_test}) { + my $ml = $objects_to_test->{$key}; + isa_ok($ml, 'Monitoring::Livestatus') or BAIL_OUT("no need to continue without a proper Monitoring::Livestatus object: ".$key); + + # dont die on errors + $ml->errors_are_fatal(0); + $ml->warnings(0); + + ######################### + # set downtime for a host and service + my $downtimes = $ml->selectall_arrayref("GET downtimes\nColumns: id"); + my $num_downtimes = 0; + $num_downtimes = scalar @{$downtimes} if defined $downtimes; + my $firsthost = $ml->selectscalar_value("GET hosts\nColumns: name\nLimit: 1"); + isnt($firsthost, undef, 'get test hostname') or BAIL_OUT($key.': got not test hostname'); + $ml->do('COMMAND ['.time().'] SCHEDULE_HOST_DOWNTIME;'.$firsthost.';'.time().';'.(time()+300).';1;0;300;'.$author.';perl test: '.$0); + my $firstservice = $ml->selectscalar_value("GET services\nColumns: description\nFilter: host_name = $firsthost\nLimit: 1"); + isnt($firstservice, undef, 'get test servicename') or BAIL_OUT('got not test servicename'); + $ml->do('COMMAND ['.time().'] SCHEDULE_SVC_DOWNTIME;'.$firsthost.';'.$firstservice.';'.time().';'.(time()+300).';1;0;300;'.$author.';perl test: '.$0); + # sometimes it takes while till the downtime is accepted + my $waited = 0; + while(scalar @{$ml->selectall_arrayref("GET downtimes\nColumns: id")} < $num_downtimes + 2) { + print "waiting for the downtime...\n"; + sleep(1); + $waited++; + BAIL_OUT('waited 30 seconds for the downtime...') if $waited > 30; + } + ######################### + + ######################### + # check tables + my $data = $ml->selectall_hashref("GET columns\nColumns: table", 'table'); + my @tables = sort keys %{$data}; + my @expected_tables = sort keys %{$expected_keys}; + is_deeply(\@tables, \@expected_tables, $key.' tables') or BAIL_OUT("got tables:\n".join(', ', @tables)."\nbut expected\n".join(', ', @expected_tables)); + + ######################### + # check keys + for my $type (keys %{$expected_keys}) { + my $filter = ""; + $filter = "Filter: time > ".(time() - 86400)."\n" if $type eq 'log'; + $filter .= "Filter: time < ".(time())."\n" if $type eq 'log'; + my $expected_keys = get_expected_keys($type); + my $statement = "GET $type\n".$filter."Limit: 1"; + $lastquery = $statement; + my $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is(ref $hash_ref, 'HASH', $type.' keys are a hash') or BAIL_OUT($type.'keys are not in hash format, got '.Dumper($hash_ref)); + my @keys = sort keys %{$hash_ref}; + is_deeply(\@keys, $expected_keys, $key.' '.$type.' table columns') or BAIL_OUT("got $type keys:\n".join(', ', @keys)."\nbut expected\n".join(', ', @{$expected_keys})); + } + + my $statement = "GET hosts\nColumns: name as hostname state\nLimit: 1"; + $lastquery = $statement; + my $hash_ref = $ml->selectrow_hashref($statement); + undef $lastquery; + isnt($hash_ref, undef, $key.' test column alias'); + is($Monitoring::Livestatus::ErrorCode, 0, $key.' test column alias') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + ######################### + # send a test command + # commands still dont work and breaks livestatus + my $rt = $ml->do('COMMAND ['.time().'] SAVE_STATE_INFORMATION'); + is($rt, '1', $key.' test command'); + + ######################### + # check for errors + #$ml->{'verbose'} = 1; + $statement = "GET hosts\nLimit: 1"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + isnt($hash_ref, undef, $key.' test error 200 body'); + is($Monitoring::Livestatus::ErrorCode, 0, $key.' test error 200 status') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "BLAH hosts"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 401 body'); + is($Monitoring::Livestatus::ErrorCode, '401', $key.' test error 401 status') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nLimit: "; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 403 body'); + is($Monitoring::Livestatus::ErrorCode, '403', $key.' test error 403 status') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET unknowntable\nLimit: 1"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 404 body'); + is($Monitoring::Livestatus::ErrorCode, '404', $key.' test error 404 status') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nColumns: unknown"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 405 body'); + TODO: { + local $TODO = 'livestatus returns wrong status'; + is($Monitoring::Livestatus::ErrorCode, '405', $key.' test error 405 status') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + }; + + ######################### + # some more broken statements + $statement = "GET "; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement); + undef $lastquery; + is($hash_ref, undef, $key.' test error 403 body'); + is($Monitoring::Livestatus::ErrorCode, '403', $key.' test error 403 status: GET ') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nColumns: name, name"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 405 body'); + is($Monitoring::Livestatus::ErrorCode, '405', $key.' test error 405 status: GET hosts\nColumns: name, name') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nColumns: "; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 405 body'); + is($Monitoring::Livestatus::ErrorCode, '405', $key.' test error 405 status: GET hosts\nColumns: ') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + ######################### + # some forbidden headers + $statement = "GET hosts\nKeepAlive: on"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 496 body'); + is($Monitoring::Livestatus::ErrorCode, '496', $key.' test error 496 status: KeepAlive: on') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nResponseHeader: fixed16"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 495 body'); + is($Monitoring::Livestatus::ErrorCode, '495', $key.' test error 495 status: ResponseHeader: fixed16') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nColumnHeaders: on"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 494 body'); + is($Monitoring::Livestatus::ErrorCode, '494', $key.' test error 494 status: ColumnHeader: on') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nOuputFormat: json"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 493 body'); + is($Monitoring::Livestatus::ErrorCode, '493', $key.' test error 493 status: OutputForma: json') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + $statement = "GET hosts\nSeparators: 0 1 2 3"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($hash_ref, undef, $key.' test error 492 body'); + is($Monitoring::Livestatus::ErrorCode, '492', $key.' test error 492 status: Seperators: 0 1 2 3') or + diag('got error: '.$Monitoring::Livestatus::ErrorMessage); + + + ######################### + # check some fancy stats queries + my $stats_query = "GET services +Stats: state = 0 as all_ok +Stats: state = 1 as all_warning +Stats: state = 2 as all_critical +Stats: state = 3 as all_unknown +Stats: state = 4 as all_pending +Stats: host_state != 0 +Stats: state = 1 +StatsAnd: 2 as all_warning_on_down_hosts +Stats: host_state != 0 +Stats: state = 2 +StatsAnd: 2 as all_critical_on_down_hosts +Stats: host_state != 0 +Stats: state = 3 +StatsAnd: 2 as all_unknown_on_down_hosts +Stats: host_state != 0 +Stats: state = 3 +Stats: active_checks_enabled = 1 +StatsAnd: 3 as all_unknown_active_on_down_hosts +Stats: state = 3 +Stats: active_checks_enabled = 1 +StatsOr: 2 as all_active_or_unknown"; + $lastquery = $stats_query; + $hash_ref = $ml->selectrow_hashref($stats_query ); + undef $lastquery; + isnt($hash_ref, undef, $key.' test fancy stats query') or + diag('got error: '.Dumper($hash_ref)); +} + + + +# generate expected keys +sub get_expected_keys { + my $type = shift; + my $skip = shift; + my @keys = @{$expected_keys->{$type}}; + + my @new_keys; + for my $key (@keys) { + my $replaced = 0; + for my $replace_with (keys %{$expected_keys}) { + if($key eq '__all_from_'.$replace_with.'__') { + $replaced = 1; + next if $skip; + my $prefix = $replace_with.'_'; + if($replace_with eq "hosts") { $prefix = 'host_'; } + if($replace_with eq "services") { $prefix = 'service_'; } + if($replace_with eq "commands") { $prefix = 'command_'; } + if($replace_with eq "contacts") { $prefix = 'contact_'; } + if($replace_with eq "servicegroups") { $prefix = 'servicegroup_'; } + if($replace_with eq "hostgroups") { $prefix = 'hostgroup_'; } + + if($type eq "log") { $prefix = 'current_'.$prefix; } + + if($type eq "servicesbygroup" and $replace_with eq 'services') { $prefix = ''; } + if($type eq "servicesbyhostgroup" and $replace_with eq 'services') { $prefix = ''; } + if($type eq "hostsbygroup" and $replace_with eq 'hosts') { $prefix = ''; } + + my $replace_keys = get_expected_keys($replace_with, 1); + for my $key2 (@{$replace_keys}) { + push @new_keys, $prefix.$key2; + } + } + } + if($replaced == 0) { + push @new_keys, $key; + } + } + + # has been fixed in 1.1.1rc + #if($type eq 'log') { + # my %keys = map { $_ => 1 } @new_keys; + # delete $keys{'current_contact_can_submit_commands'}; + # delete $keys{'current_contact_host_notifications_enabled'}; + # delete $keys{'current_contact_in_host_notification_period'}; + # delete $keys{'current_contact_in_service_notification_period'}; + # delete $keys{'current_contact_service_notifications_enabled'}; + # @new_keys = keys %keys; + #} + + my @return = sort @new_keys; + return(\@return); +} diff --git a/api/perl/t/31-Monitoring-Livestatus-MULTI-live-test.t b/api/perl/t/31-Monitoring-Livestatus-MULTI-live-test.t new file mode 100644 index 0000000..fb7fa94 --- /dev/null +++ b/api/perl/t/31-Monitoring-Livestatus-MULTI-live-test.t @@ -0,0 +1,95 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More; +use Data::Dumper; + +if ( ! defined $ENV{TEST_SOCKET} or !defined $ENV{TEST_SERVER} ) { + my $msg = 'Author test. Set $ENV{TEST_SOCKET} and $ENV{TEST_SERVER} to run'; + plan( skip_all => $msg ); +} else { + plan( tests => 22 ); +} + +use_ok('Monitoring::Livestatus::MULTI'); + +######################### +# create new test object +my $objects_to_test = { + 'multi_one' => Monitoring::Livestatus::MULTI->new( peer => [ $ENV{TEST_SERVER} ], warnings => 0 ), + 'multi_two' => Monitoring::Livestatus::MULTI->new( peer => [ $ENV{TEST_SERVER}, $ENV{TEST_SOCKET} ], warnings => 0 ), + 'multi_three' => Monitoring::Livestatus::MULTI->new( + 'verbose' => '0', + 'warnings' => '0', + 'timeout' => '10', + 'peer' => [ + { 'name' => 'Mon 1', 'peer' => $ENV{TEST_SERVER} }, + { 'name' => 'Mon 2', 'peer' => $ENV{TEST_SOCKET} }, + ], + 'keepalive' => '1' + ), +}; + +# dont die on errors +#$ml->errors_are_fatal(0); + +for my $key (keys %{$objects_to_test}) { + my $ml = $objects_to_test->{$key}; + isa_ok($ml, 'Monitoring::Livestatus::MULTI') or BAIL_OUT("no need to continue without a proper Monitoring::Livestatus::MULTI object"); + + ######################### + # DATA INTEGRITY + ######################### + + my $statement = "GET hosts\nColumns: state name alias\nLimit: 1"; + my $data1 = $ml->selectall_arrayref($statement, {Slice => 1}); + my $data2 = $ml->selectall_arrayref($statement, {Slice => 1, AddPeer => 1}); + for my $data (@{$data2}) { + delete $data->{'peer_name'}; + delete $data->{'peer_addr'}; + delete $data->{'peer_key'}; + } + is_deeply($data1, $data2, "data integrity with peers added and Column"); + + $statement = "GET hosts\nLimit: 1"; + $data1 = $ml->selectall_arrayref($statement, {Slice => 1, Deepcopy => 1}); + $data2 = $ml->selectall_arrayref($statement, {Slice => 1, AddPeer => 1, Deepcopy => 1}); + for my $data (@{$data2}) { + delete $data->{'peer_name'}; + delete $data->{'peer_addr'}; + delete $data->{'peer_key'}; + } + is_deeply($data1, $data2, "data integrity with peers added without Columns"); + + ######################### + # try to change result set to scalar + for my $data (@{$data1}) { $data->{'peer_name'} = 1; } + for my $data (@{$data2}) { $data->{'peer_name'} = 1; } + is_deeply($data1, $data2, "data integrity with changed result set"); + + ######################### + # try to change result set to hash + for my $data (@{$data1}) { $data->{'peer_name'} = {}; } + for my $data (@{$data2}) { $data->{'peer_name'} = {}; } + is_deeply($data1, $data2, "data integrity with changed result set"); + + ######################### + # BACKENDS + ######################### + my @backends = $ml->peer_key(); + $data1 = $ml->selectall_arrayref($statement, {Slice => 1}); + $data2 = $ml->selectall_arrayref($statement, {Slice => 1, Backend => \@backends }); + is_deeply($data1, $data2, "data integrity with backends"); + + ######################### + # BUGS + ######################### + + ######################### + # Bug: Can't use string ("flap") as an ARRAY ref while "strict refs" in use at Monitoring/Livestatus/MULTI.pm line 206. + $statement = "GET servicegroups\nColumns: name alias\nFilter: name = flap\nLimit: 1"; + $data1 = $ml->selectrow_array($statement); + isnt($data1, undef, "bug check: Can't use string (\"group\")..."); +} diff --git a/api/perl/t/32-Monitoring-Livestatus-backend-test.t b/api/perl/t/32-Monitoring-Livestatus-backend-test.t new file mode 100644 index 0000000..cce6e16 --- /dev/null +++ b/api/perl/t/32-Monitoring-Livestatus-backend-test.t @@ -0,0 +1,106 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Carp; +use Test::More; +use Data::Dumper; + +if ( ! defined $ENV{TEST_SOCKET} or !defined $ENV{TEST_SERVER} or !defined $ENV{TEST_BACKEND} ) { + my $msg = 'Author test. Set $ENV{TEST_SOCKET} and $ENV{TEST_SERVER} and $ENV{TEST_BACKEND} to run'; + plan( skip_all => $msg ); +} else { + # we dont know yet how many tests we got + plan( tests => 55237 ); +} + +# set an alarm +my $lastquery; +$SIG{ALRM} = sub { + my @caller = caller; + $lastquery =~ s/\n+/\n/g; + print STDERR 'last query: '.$lastquery."\n" if defined $lastquery; + confess "timeout reached:".Dumper(\@caller)."\n" +}; + +use_ok('Monitoring::Livestatus'); + +######################### +my $objects_to_test = { + # UNIX + '01 unix_single_arg' => Monitoring::Livestatus::UNIX->new( $ENV{TEST_SOCKET} ), + + # TCP + '02 inet_single_arg' => Monitoring::Livestatus::INET->new( $ENV{TEST_SERVER} ), + + # MULTI + '03 multi_keepalive' => Monitoring::Livestatus->new( [ $ENV{TEST_SERVER}, $ENV{TEST_SOCKET} ] ), +}; + +for my $key (sort keys %{$objects_to_test}) { + my $ml = $objects_to_test->{$key}; + isa_ok($ml, 'Monitoring::Livestatus') or BAIL_OUT("no need to continue without a proper Monitoring::Livestatus object: ".$key); + + # dont die on errors + $ml->errors_are_fatal(0); + $ml->warnings(0); + + ######################### + # get tables + my $data = $ml->selectall_hashref("GET columns\nColumns: table", 'table'); + my @tables = sort keys %{$data}; + + ######################### + # check keys + for my $type (@tables) { + alarm(120); + my $filter = ""; + $filter = "Filter: time > ".(time() - 86400)."\n" if $type eq 'log'; + $filter .= "Filter: time < ".(time())."\n" if $type eq 'log'; + my $statement = "GET $type\n".$filter."Limit: 1"; + $lastquery = $statement; + my $keys = $ml->selectrow_hashref($statement ); + undef $lastquery; + is(ref $keys, 'HASH', $type.' keys are a hash');# or BAIL_OUT('keys are not in hash format, got '.Dumper($keys)); + + # status has no filter implemented + next if $type eq 'status'; + + for my $key (keys %{$keys}) { + my $value = $keys->{$key}; + if(index($value, ',') > 0) { my @vals = split /,/, $value; $value = $vals[0]; } + my $typefilter = "Filter: $key >= $value\n"; + if($value eq '') { + $typefilter = "Filter: $key =\n"; + } + my $statement = "GET $type\n".$filter.$typefilter."Limit: 1"; + $lastquery = $statement; + my $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($Monitoring::Livestatus::ErrorCode, 0, "GET ".$type." Filter: ".$key." >= ".$value) or BAIL_OUT("query failed: ".$statement); + #isnt($hash_ref, undef, "GET ".$type." Filter: ".$key." >= ".$value);# or BAIL_OUT("got undef for ".$statement); + + # send test stats query + my $stats_query = [ $key.' = '.$value, 'std '.$key, 'min '.$key, 'max '.$key, 'avg '.$key, 'sum '.$key ]; + for my $stats_part (@{$stats_query}) { + my $statement = "GET $type\n".$filter.$typefilter."\nStats: $stats_part"; + $lastquery = $statement; + my $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($Monitoring::Livestatus::ErrorCode, 0, "GET ".$type." Filter: ".$key." >= ".$value." Stats: $stats_part") or BAIL_OUT("query failed:\n".$statement); + + $statement = "GET $type\n".$filter.$typefilter."\nStats: $stats_part\nStatsGroupBy: $key"; + $lastquery = $statement; + $hash_ref = $ml->selectrow_hashref($statement ); + undef $lastquery; + is($Monitoring::Livestatus::ErrorCode, 0, "GET ".$type." Filter: ".$key." >= ".$value." Stats: $stats_part StatsGroupBy: $key") or BAIL_OUT("query failed:\n".$statement); + } + + # wait till backend is started up again + if(!defined $hash_ref and $Monitoring::Livestatus::ErrorCode > 200) { + sleep(2); + } + } + } +} diff --git a/api/perl/t/33-Monitoring-Livestatus-test_socket_timeout.t b/api/perl/t/33-Monitoring-Livestatus-test_socket_timeout.t new file mode 100644 index 0000000..84e3ce9 --- /dev/null +++ b/api/perl/t/33-Monitoring-Livestatus-test_socket_timeout.t @@ -0,0 +1,74 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Test::More; +use Data::Dumper; + +if ( !defined $ENV{TEST_SERVER} ) { + my $msg = 'Author test. Set $ENV{TEST_SOCKET} and $ENV{TEST_SERVER} to run'; + plan( skip_all => $msg ); +} else { + plan( tests => 7 ); +} + +# set an alarm +my $lastquery; +$SIG{ALRM} = sub { + my @caller = caller; + print STDERR 'last query: '.$lastquery if defined $lastquery; + die "timeout reached:".Dumper(\@caller)."\n" +}; +alarm(30); + +use_ok('Monitoring::Livestatus'); + +#use Log::Log4perl qw(:easy); +#Log::Log4perl->easy_init($DEBUG); + +######################### +# Test Query +######################### +my $statement = "GET hosts\nColumns: alias\nFilter: name = host1"; + +######################### +my $objects_to_test = { + # create inet object with hash args + '01 inet_hash_args' => Monitoring::Livestatus->new( + verbose => 0, + server => $ENV{TEST_SERVER}, + keepalive => 1, + timeout => 3, + retries_on_connection_error => 0, +# logger => get_logger(), + ), + + # create inet object with a single arg + '02 inet_single_arg' => Monitoring::Livestatus::INET->new( $ENV{TEST_SERVER} ), + +}; + +for my $key (sort keys %{$objects_to_test}) { + my $ml = $objects_to_test->{$key}; + isa_ok($ml, 'Monitoring::Livestatus'); + + # we dont need warnings for testing + $ml->warnings(0); + + ######################### + my $ary_ref = $ml->selectall_arrayref($statement); + is($Monitoring::Livestatus::ErrorCode, 0, 'Query Status 0'); + #is_deeply($ary_ref, $selectall_arrayref1, 'selectall_arrayref($statement)') + # or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectall_arrayref1)); + + sleep(10); + + $ary_ref = $ml->selectall_arrayref($statement); + is($Monitoring::Livestatus::ErrorCode, 0, 'Query Status 0'); + #is_deeply($ary_ref, $selectall_arrayref1, 'selectall_arrayref($statement)') + # or diag("got: ".Dumper($ary_ref)."\nbut expected ".Dumper($selectall_arrayref1)); + + #print Dumper($Monitoring::Livestatus::ErrorCode); + #print Dumper($Monitoring::Livestatus::ErrorMessage); +} diff --git a/api/perl/t/34-Monitoring-Livestatus-utf8_support.t b/api/perl/t/34-Monitoring-Livestatus-utf8_support.t new file mode 100644 index 0000000..47e31d5 --- /dev/null +++ b/api/perl/t/34-Monitoring-Livestatus-utf8_support.t @@ -0,0 +1,78 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Encode; +use Test::More; +use Data::Dumper; + +if ( !defined $ENV{TEST_SERVER} ) { + my $msg = 'Author test. Set $ENV{TEST_SOCKET} and $ENV{TEST_SERVER} to run'; + plan( skip_all => $msg ); +} else { + plan( tests => 9 ); +} + +use_ok('Monitoring::Livestatus'); + +#use Log::Log4perl qw(:easy); +#Log::Log4perl->easy_init($DEBUG); + +######################### +my $objects_to_test = { + # create inet object with hash args + '01 inet_hash_args' => Monitoring::Livestatus->new( + verbose => 0, + server => $ENV{TEST_SERVER}, + keepalive => 1, + timeout => 3, + retries_on_connection_error => 0, +# logger => get_logger(), + ), + + # create inet object with a single arg + '02 inet_single_arg' => Monitoring::Livestatus::INET->new( $ENV{TEST_SERVER} ), +}; + +my $author = 'Monitoring::Livestatus test'; +for my $key (sort keys %{$objects_to_test}) { + my $ml = $objects_to_test->{$key}; + isa_ok($ml, 'Monitoring::Livestatus'); + + # we dont need warnings for testing + $ml->warnings(0); + + ######################### + my $downtimes = $ml->selectall_arrayref("GET downtimes\nColumns: id"); + my $num_downtimes = 0; + $num_downtimes = scalar @{$downtimes} if defined $downtimes; + + ######################### + # get a test host + my $firsthost = $ml->selectscalar_value("GET hosts\nColumns: name\nLimit: 1"); + isnt($firsthost, undef, 'get test hostname') or BAIL_OUT($key.': got not test hostname'); + + my $expect = "aa ²&é\"'''(§è!çà)- %s ''%s'' aa ~ € bb"; + #my $expect = "öäüß"; + my $teststrings = [ + $expect, + "aa \x{c2}\x{b2}&\x{c3}\x{a9}\"'''(\x{c2}\x{a7}\x{c3}\x{a8}!\x{c3}\x{a7}\x{c3}\x{a0})- %s ''%s'' aa ~ \x{e2}\x{82}\x{ac} bb", + ]; + for my $string (@{$teststrings}) { + $ml->do('COMMAND ['.time().'] SCHEDULE_HOST_DOWNTIME;'.$firsthost.';'.time().';'.(time()+300).';1;0;300;'.$author.';'.$string); + + # sometimes it takes while till the downtime is accepted + my $waited = 0; + while($downtimes = $ml->selectall_arrayref("GET downtimes\nColumns: id comment", { Slice => 1 }) and scalar @{$downtimes} < $num_downtimes + 1) { + print "waiting for the downtime...\n"; + sleep(1); + $waited++; + BAIL_OUT('waited 30 seconds for the downtime...') if $waited > 30; + } + + my $last_downtime = pop @{$downtimes}; + #utf8::decode($expect); + is($last_downtime->{'comment'}, $expect, 'get same utf8 comment: got '.Dumper($last_downtime)); + } +} diff --git a/api/perl/t/35-Monitoring-Livestatus-callbacks_support.t b/api/perl/t/35-Monitoring-Livestatus-callbacks_support.t new file mode 100644 index 0000000..3af3eac --- /dev/null +++ b/api/perl/t/35-Monitoring-Livestatus-callbacks_support.t @@ -0,0 +1,53 @@ +#!/usr/bin/env perl + +######################### + +use strict; +use Encode; +use Test::More; +use Data::Dumper; + +if ( !defined $ENV{TEST_SERVER} ) { + my $msg = 'Author test. Set $ENV{TEST_SOCKET} and $ENV{TEST_SERVER} to run'; + plan( skip_all => $msg ); +} else { + plan( tests => 15 ); +} + +use_ok('Monitoring::Livestatus'); + +#use Log::Log4perl qw(:easy); +#Log::Log4perl->easy_init($DEBUG); + +######################### +my $objects_to_test = { + # create inet object with hash args + '01 inet_hash_args' => Monitoring::Livestatus->new( + verbose => 0, + server => $ENV{TEST_SERVER}, + keepalive => 1, + timeout => 3, + retries_on_connection_error => 0, +# logger => get_logger(), + ), + + # create inet object with a single arg + '02 inet_single_arg' => Monitoring::Livestatus::INET->new( $ENV{TEST_SERVER} ), +}; + +for my $key (sort keys %{$objects_to_test}) { + my $ml = $objects_to_test->{$key}; + isa_ok($ml, 'Monitoring::Livestatus'); + + my $got = $ml->selectall_arrayref("GET hosts\nColumns: name alias state\nLimit: 1", { Slice => 1, callbacks => { 'c1' => sub { return $_[0]->{'alias'}; } } }); + isnt($got->[0]->{'alias'}, undef, 'got a test host'); + is($got->[0]->{'alias'}, $got->[0]->{'c1'}, 'callback for sliced results'); + + $got = $ml->selectall_arrayref("GET hosts\nColumns: name alias state\nLimit: 1", { Slice => 1, callbacks => { 'name' => sub { return $_[0]->{'alias'}; } } }); + isnt($got->[0]->{'alias'}, undef, 'got a test host'); + is($got->[0]->{'alias'}, $got->[0]->{'name'}, 'callback for sliced results which overwrites key'); + + $got = $ml->selectall_arrayref("GET hosts\nColumns: name alias state\nLimit: 1", { callbacks => { 'c1' => sub { return $_[0]->[1]; } } }); + isnt($got->[0]->[1], undef, 'got a test host'); + is($got->[0]->[1], $got->[0]->[3], 'callback for non sliced results'); +} diff --git a/api/perl/t/97-Pod.t b/api/perl/t/97-Pod.t new file mode 100644 index 0000000..0475102 --- /dev/null +++ b/api/perl/t/97-Pod.t @@ -0,0 +1,9 @@ +use strict; +use warnings; +use Test::More; + +eval "use Test::Pod 1.14"; +plan skip_all => 'Test::Pod 1.14 required' if $@; +plan skip_all => 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.' unless $ENV{TEST_AUTHOR}; + +all_pod_files_ok(); diff --git a/api/perl/t/98-Pod-Coverage.t b/api/perl/t/98-Pod-Coverage.t new file mode 100644 index 0000000..2858336 --- /dev/null +++ b/api/perl/t/98-Pod-Coverage.t @@ -0,0 +1,23 @@ +#!/usr/bin/env perl +# +# $Id$ +# +use strict; +use warnings; +use File::Spec; +use Test::More; + +if ( not $ENV{TEST_AUTHOR} ) { + my $msg = 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.'; + plan( skip_all => $msg ); +} + +eval { require Test::Pod::Coverage; }; + +if ( $@ ) { + my $msg = 'Test::Pod::Coverage required to criticise pod'; + plan( skip_all => $msg ); +} + +eval "use Test::Pod::Coverage 1.00"; +all_pod_coverage_ok(); diff --git a/api/perl/t/99-Perl-Critic.t b/api/perl/t/99-Perl-Critic.t new file mode 100644 index 0000000..85b88f3 --- /dev/null +++ b/api/perl/t/99-Perl-Critic.t @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +# +# $Id$ +# +use strict; +use warnings; +use File::Spec; +use Test::More; + +if ( not $ENV{TEST_AUTHOR} ) { + my $msg = 'Author test. Set $ENV{TEST_AUTHOR} to a true value to run.'; + plan( skip_all => $msg ); +} + +eval { require Test::Perl::Critic; }; + +if ( $@ ) { + my $msg = 'Test::Perl::Critic required to criticise code'; + plan( skip_all => $msg ); +} + +my $rcfile = File::Spec->catfile( 't', 'perlcriticrc' ); +Test::Perl::Critic->import( -profile => $rcfile ); +all_critic_ok(); diff --git a/api/perl/t/perlcriticrc b/api/perl/t/perlcriticrc new file mode 100644 index 0000000..f7e4721 --- /dev/null +++ b/api/perl/t/perlcriticrc @@ -0,0 +1,286 @@ +############################################################################## +# This Perl::Critic configuration file sets the Policy severity levels +# according to Damian Conway's own personal recommendations. Feel free to +# use this as your own, or make modifications. +############################################################################## + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitAccessOfPrivateData] +severity = 3 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitLvalueSubstr] +severity = 3 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitReverseSortBlock] +severity = 1 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitSleepViaSelect] +severity = 5 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitStringyEval] +severity = 5 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitStringySplit] +severity = 2 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitUniversalCan] +severity = 4 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitUniversalIsa] +severity = 4 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitVoidGrep] +severity = 3 + +[Perl::Critic::Policy::BuiltinFunctions::ProhibitVoidMap] +severity = 3 + +[Perl::Critic::Policy::BuiltinFunctions::RequireBlockGrep] +severity = 4 + +[Perl::Critic::Policy::BuiltinFunctions::RequireBlockMap] +severity = 4 + +[Perl::Critic::Policy::BuiltinFunctions::RequireGlobFunction] +severity = 5 + +[Perl::Critic::Policy::BuiltinFunctions::RequireSimpleSortBlock] +severity = 3 + +[Perl::Critic::Policy::ClassHierarchies::ProhibitAutoloading] +severity = 3 + +[Perl::Critic::Policy::ClassHierarchies::ProhibitExplicitISA] +severity = 4 + +[Perl::Critic::Policy::ClassHierarchies::ProhibitOneArgBless] +severity = 5 + +[Perl::Critic::Policy::CodeLayout::ProhibitHardTabs] +severity = 3 + +[Perl::Critic::Policy::CodeLayout::ProhibitParensWithBuiltins] +severity = 1 + +[Perl::Critic::Policy::CodeLayout::ProhibitQuotedWordLists] +severity = 2 + +[Perl::Critic::Policy::CodeLayout::RequireConsistentNewlines] +severity = 4 + +[Perl::Critic::Policy::CodeLayout::RequireTidyCode] +severity = 1 + +[Perl::Critic::Policy::CodeLayout::RequireTrailingCommas] +severity = 3 + +[Perl::Critic::Policy::ControlStructures::ProhibitCStyleForLoops] +severity = 3 + +[Perl::Critic::Policy::ControlStructures::ProhibitCascadingIfElse] +severity = 3 + +[Perl::Critic::Policy::ControlStructures::ProhibitDeepNests] +severity = 3 + +[Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions] +severity = 5 + +[Perl::Critic::Policy::ControlStructures::ProhibitPostfixControls] +severity = 4 + +[Perl::Critic::Policy::ControlStructures::ProhibitUnlessBlocks] +severity = 4 + +[Perl::Critic::Policy::ControlStructures::ProhibitUnreachableCode] +severity = 4 + +[Perl::Critic::Policy::ControlStructures::ProhibitUntilBlocks] +severity = 4 + +[Perl::Critic::Policy::Documentation::RequirePodAtEnd] +severity = 2 + +[Perl::Critic::Policy::Documentation::RequirePodSections] +severity = 2 + +[Perl::Critic::Policy::ErrorHandling::RequireCarping] +severity = 4 + +[Perl::Critic::Policy::InputOutput::ProhibitBacktickOperators] +severity = 3 + +[Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles] +severity = 5 + +[Perl::Critic::Policy::InputOutput::ProhibitInteractiveTest] +severity = 4 + +[Perl::Critic::Policy::InputOutput::ProhibitOneArgSelect] +severity = 4 + +[Perl::Critic::Policy::InputOutput::ProhibitReadlineInForLoop] +severity = 5 + +[Perl::Critic::Policy::InputOutput::ProhibitTwoArgOpen] +severity = 4 + +[Perl::Critic::Policy::InputOutput::RequireBracedFileHandleWithPrint] +severity = 3 + +[Perl::Critic::Policy::Miscellanea::ProhibitFormats] +severity = 3 + +[Perl::Critic::Policy::Miscellanea::ProhibitTies] +severity = 4 + +[-Perl::Critic::Policy::Miscellanea::RequireRcsKeywords] + +[Perl::Critic::Policy::Modules::ProhibitAutomaticExportation] +severity = 4 + +[Perl::Critic::Policy::Modules::ProhibitEvilModules] +severity = 5 + +[Perl::Critic::Policy::Modules::ProhibitMultiplePackages] +severity = 4 + +[Perl::Critic::Policy::Modules::RequireBarewordIncludes] +severity = 5 + +[Perl::Critic::Policy::Modules::RequireEndWithOne] +severity = 4 + +[Perl::Critic::Policy::Modules::RequireExplicitPackage] +severity = 4 + +[Perl::Critic::Policy::Modules::RequireFilenameMatchesPackage] +severity = 5 + +[Perl::Critic::Policy::Modules::RequireVersionVar] +severity = 4 + +[Perl::Critic::Policy::NamingConventions::ProhibitAmbiguousNames] +severity = 3 + +[Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseSubs] +severity = 1 + +[Perl::Critic::Policy::NamingConventions::ProhibitMixedCaseVars] +severity = 1 + +[Perl::Critic::Policy::References::ProhibitDoubleSigils] +severity = 4 + +[Perl::Critic::Policy::RegularExpressions::ProhibitCaptureWithoutTest] +severity = 4 + +[Perl::Critic::Policy::RegularExpressions::RequireExtendedFormatting] +severity = 5 + +[Perl::Critic::Policy::RegularExpressions::RequireLineBoundaryMatching] +severity = 5 + +[Perl::Critic::Policy::Subroutines::ProhibitAmpersandSigils] +severity = 2 + +[Perl::Critic::Policy::Subroutines::ProhibitBuiltinHomonyms] +severity = 4 + +[Perl::Critic::Policy::Subroutines::ProhibitExcessComplexity] +severity = 3 + +[Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef] +severity = 5 + +[Perl::Critic::Policy::Subroutines::ProhibitSubroutinePrototypes] +severity = 4 + +[Perl::Critic::Policy::Subroutines::ProtectPrivateSubs] +severity = 3 + +[Perl::Critic::Policy::Subroutines::RequireFinalReturn] +severity = 5 + +[Perl::Critic::Policy::TestingAndDebugging::ProhibitNoStrict] +severity = 5 + +[Perl::Critic::Policy::TestingAndDebugging::ProhibitNoWarnings] +severity = 4 + +[Perl::Critic::Policy::TestingAndDebugging::ProhibitProlongedStrictureOverride] +severity = 4 + +[Perl::Critic::Policy::TestingAndDebugging::RequireTestLabels] +severity = 3 + +[Perl::Critic::Policy::TestingAndDebugging::RequireUseStrict] +severity = 5 + +[Perl::Critic::Policy::TestingAndDebugging::RequireUseWarnings] +severity = 4 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitConstantPragma] +severity = 4 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitEmptyQuotes] +severity = 2 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitEscapedCharacters] +severity = 2 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitInterpolationOfLiterals] +severity = 1 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitLeadingZeros] +severity = 5 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitMismatchedOperators] +severity = 2 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitMixedBooleanOperators] +severity = 4 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitNoisyQuotes] +severity = 2 + +[Perl::Critic::Policy::ValuesAndExpressions::ProhibitVersionStrings] +severity = 3 + +[Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars] +severity = 1 + +[Perl::Critic::Policy::ValuesAndExpressions::RequireNumberSeparators] +severity = 2 + +[Perl::Critic::Policy::ValuesAndExpressions::RequireQuotedHeredocTerminator] +severity = 4 + +[Perl::Critic::Policy::ValuesAndExpressions::RequireUpperCaseHeredocTerminator] +severity = 4 + +[Perl::Critic::Policy::Variables::ProhibitConditionalDeclarations] +severity = 5 + +[Perl::Critic::Policy::Variables::ProhibitLocalVars] +severity = 2 + +[Perl::Critic::Policy::Variables::ProhibitMatchVars] +severity = 4 + +[Perl::Critic::Policy::Variables::ProhibitPackageVars] +severity = 3 + +[Perl::Critic::Policy::Variables::ProhibitPunctuationVars] +severity = 2 + +[Perl::Critic::Policy::Variables::ProtectPrivateVars] +severity = 3 + +[Perl::Critic::Policy::Variables::RequireInitializationForLocalVars] +severity = 5 + +[Perl::Critic::Policy::Variables::RequireLexicalLoopIterators] +severity = 5 + +[Perl::Critic::Policy::Variables::RequireNegativeIndices] +severity = 4 \ No newline at end of file diff --git a/api/python/README b/api/python/README new file mode 100644 index 0000000..2fc8471 --- /dev/null +++ b/api/python/README @@ -0,0 +1,23 @@ +This directory contains a very efficient API to MK Livestatus +for Python. It is directly taken from the Multisite GUI and +has the following features: + +* It supports keep alive +* It returns typed values +* It support transparent multi-site access +* It supports persistent connection caching +* It supports parallelized queries (though still single-threaded) +* It supports detection of dead sites (via "status_host") + +Please look at the two examples: + +example.py: Example for a single site +example_multisite.py: Example querying several sites + +Both example are written to be run within an OMD instance +and need no further configuration. + +If you are not using OMD, you need to modify the examples +and enter the correct path to you livestatus socket. +Or even better: give OMD a try --> omdistro.org. This will +make you live *really* easier! diff --git a/api/python/example.py b/api/python/example.py new file mode 100755 index 0000000..935cec0 --- /dev/null +++ b/api/python/example.py @@ -0,0 +1,72 @@ +#!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +import os, sys +import livestatus + +try: + omd_root = os.getenv("OMD_ROOT") + socket_path = "unix:" + omd_root + "/tmp/run/live" +except: + sys.stderr.write("This example is indented to run in an OMD site\n") + sys.stderr.write("Please change socket_path in this example, if you are\n") + sys.stderr.write("not using OMD.\n") + sys.exit(1) + +try: + # Make a single connection for each query + print "\nPerformance:" + for key, value in livestatus.SingleSiteConnection(socket_path).query_row_assoc("GET status").items(): + print "%-30s: %s" % (key, value) + print "\nHosts:" + hosts = livestatus.SingleSiteConnection(socket_path).query_table("GET hosts\nColumns: name alias address") + for name, alias, address in hosts: + print "%-16s %-16s %s" % (name, address, alias) + + # Do several queries in one connection + conn = livestatus.SingleSiteConnection(socket_path) + num_up = conn.query_value("GET hosts\nStats: hard_state = 0") + print "\nHosts up: %d" % num_up + + stats = conn.query_row( + "GET services\n" + "Stats: state = 0\n" + "Stats: state = 1\n" + "Stats: state = 2\n" + "Stats: state = 3\n") + print "Service stats: %d/%d/%d/%d" % tuple(stats) + + print "List of commands: %s" % \ + ", ".join(conn.query_column("GET commands\nColumns: name")) + + print "Query error:" + conn.query_value("GET hosts\nColumns: hirni") + + +except Exception, e: # livestatus.MKLivestatusException, e: + print "Livestatus error: %s" % str(e) + + diff --git a/api/python/example_multisite.py b/api/python/example_multisite.py new file mode 100755 index 0000000..db89d37 --- /dev/null +++ b/api/python/example_multisite.py @@ -0,0 +1,94 @@ +#!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +import os +import sys +import livestatus + +try: + omd_root = os.getenv("OMD_ROOT") + socket_path = "unix:" + omd_root + "/tmp/run/live" +except: + sys.stderr.write("This example is indented to run in an OMD site\n") + sys.stderr.write("Please change socket_path in this example, if you are\n") + sys.stderr.write("not using OMD.\n") + sys.exit(1) + + +sites = { + "muc" : { + "socket" : socket_path, + "alias" : "Munich", + }, + "sitea" : { + "alias" : "Augsburg", + "socket" : "tcp:sitea:6557", + "nagios_url" : "/nagios/", + "timeout" : 2, + }, + "siteb" : { + "alias" : "Berlin", + "socket" : "tcp:siteb:6557", + "nagios_url" : "/nagios/", + "timeout" : 10, + }, +} + +c = livestatus.MultiSiteConnection(sites) +c.set_prepend_site(True) +print c.query("GET hosts\nColumns: name state\n") +c.set_prepend_site(False) +print c.query("GET hosts\nColumns: name state\n") + +# Beware: When doing stats, you need to aggregate yourself: +print sum(c.query_column("GET hosts\nStats: state >= 0\n")) + +# Detect errors: +sites = { + "muc" : { + "socket" : "unix:/var/run/nagios/rw/live", + "alias" : "Munich", + }, + "sitea" : { + "alias" : "Augsburg", + "socket" : "tcp:sitea:6558", # BROKEN + "nagios_url" : "/nagios/", + "timeout" : 2, + }, + "siteb" : { + "alias" : "Berlin", + "socket" : "tcp:siteb:6557", + "nagios_url" : "/nagios/", + "timeout" : 10, + }, +} + +c = livestatus.MultiSiteConnection(sites) +for name, state in c.query("GET hosts\nColumns: name state\n"): + print "%-15s: %d" % (name, state) +print "Dead sites:" +for sitename, info in c.dead_sites().items(): + print "%s: %s" % (sitename, info["exception"]) diff --git a/api/python/livestatus.py b/api/python/livestatus.py new file mode 100644 index 0000000..9f73068 --- /dev/null +++ b/api/python/livestatus.py @@ -0,0 +1,839 @@ +#!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +import socket, time, re, os +import ast + +"""MK Livestatus Python API""" + +# .--Globals-------------------------------------------------------------. +# | ____ _ _ _ | +# | / ___| | ___ | |__ __ _| |___ | +# | | | _| |/ _ \| '_ \ / _` | / __| | +# | | |_| | | (_) | |_) | (_| | \__ \ | +# | \____|_|\___/|_.__/ \__,_|_|___/ | +# | | +# +----------------------------------------------------------------------+ +# | Global variables and Exception classes | +# '----------------------------------------------------------------------' + +# Keep a global array of persistant connections +persistent_connections = {} + +# Regular expression for removing Cache: headers if caching is not allowed +remove_cache_regex = re.compile("\nCache:[^\n]*") + +class MKLivestatusException(Exception): + + def __init__(self, value): + self.parameter = value + super(MKLivestatusException, self).__init__(value) + + def __str__(self): + return str(self.parameter) + +class MKLivestatusSocketError(MKLivestatusException): + pass + +class MKLivestatusSocketClosed(MKLivestatusSocketError): + pass + +class MKLivestatusConfigError(MKLivestatusException): + pass + +class MKLivestatusQueryError(MKLivestatusException): + pass + +class MKLivestatusNotFoundError(MKLivestatusException): + def __str__(self): + return "No matching entries found for query %s" % str(self.parameter) + +class MKLivestatusTableNotFoundError(MKLivestatusException): + pass + +# We need some unique value here +NO_DEFAULT = lambda: None + + + +#. +# .--Helpers-------------------------------------------------------------. +# | _ _ _ | +# | | | | | ___| |_ __ ___ _ __ ___ | +# | | |_| |/ _ \ | '_ \ / _ \ '__/ __| | +# | | _ | __/ | |_) | __/ | \__ \ | +# | |_| |_|\___|_| .__/ \___|_| |___/ | +# | |_| | +# +----------------------------------------------------------------------+ +# | Helper class implementing some generic shortcut functions, e.g. | +# | for fetching just one row or one single value. | +# '----------------------------------------------------------------------' + +class Helpers: + def query(self, query, add_headers = ""): + raise NotImplementedError() + + + def query_value(self, query, deflt = NO_DEFAULT): + """Issues a query that returns exactly one line and one columns and returns + the response as a single value""" + result = self.query(query, "ColumnHeaders: off\n") + try: + return result[0][0] + except: + if deflt == NO_DEFAULT: + raise MKLivestatusNotFoundError(query) + else: + return deflt + + + def query_row(self, query): + """Issues a query that returns one line of data and returns the elements + of that line as list""" + result = self.query(query, "ColumnHeaders: off\n") + try: + return result[0] + except IndexError: + raise MKLivestatusNotFoundError(query) + + + def query_row_assoc(self, query): + """Issues a query that returns one line of data and returns the elements + of that line as a dictionary from column names to values""" + r = self.query(query, "ColumnHeaders: on\n")[0:2] + return dict(zip(r[0], r[1])) + + + def query_column(self, query): + """Issues a query that returns exactly one column and returns the values + of all lines in that column as a single list""" + return [ l[0] for l in self.query(query, "ColumnHeaders: off\n") ] + + + def query_column_unique(self, query): + """Issues a query that returns exactly one column and returns the values + of all lines with duplicates removed""" + result = [] + for line in self.query(query, "ColumnHeaders: off\n"): + if line[0] not in result: + result.append(line[0]) + return result + + + def query_table(self, query): + """Issues a query that may return multiple lines and columns and returns + a list of lists""" + return self.query(query, "ColumnHeaders: off\n") + + + def query_table_assoc(self, query): + """Issues a query that may return multiple lines and columns and returns + a dictionary from column names to values for each line. This can be + very ineffective for large response sets.""" + response = self.query(query, "ColumnHeaders: on\n") + headers = response[0] + result = [] + for line in response[1:]: + result.append(dict(zip(headers, line))) + return result + + + def query_summed_stats(self, query, add_headers = ""): + """Conveniance function for adding up numbers from Stats queries + Adds up results column-wise. This is useful for multisite queries.""" + data = self.query(query, add_headers) + if len(data) == 1: + return data[0] + elif len(data) == 0: + raise MKLivestatusNotFoundError("Empty result to Stats-Query") + + result = [] + for x in range(0, len(data[0])): + result.append(sum([row[x] for row in data])) + return result + + +# TODO: Add more functionality to the Query class: +# - set_prepend_site +# - set_only_sites +# - set_auth_domain +# All these are mostly set for a single query and reset back to another +# value after the query. But nearly all of these usages does not care +# about resetting the option in case of an exception. This could be +# handled better using the query class +class Query(object): + """This object can be passed to all livestatus methods accepting a livestatus + query. The object can be used to hand over the handling code some flags, for + example to influence the error handling during query processing.""" + + default_suppressed_exceptions = [MKLivestatusTableNotFoundError] + + def __init__(self, query, suppress_exceptions=None): + super(Query, self).__init__() + + self._query = self._ensure_unicode(query) + + if suppress_exceptions == None: + self.suppress_exceptions = self.default_suppressed_exceptions + else: + self.suppress_exceptions = suppress_exceptions + + + def _ensure_unicode(self, thing): + try: + return unicode(thing) + except UnicodeDecodeError: + return thing.decode("utf-8") + + + def __unicode__(self): + return self._query + + + def __str__(self): + return self._query.encode("utf-8") + + + +#. +# .--BaseConnection----------------------------------------------------------. +# | ____ ____ _ _ | +# || __ ) __ _ ___ ___ / ___|___ _ __ _ __ ___ ___| |_(_) ___ _ __ | +# || _ \ / _` / __|/ _ \ | / _ \| '_ \| '_ \ / _ \/ __| __| |/ _ \ | '_ \ | +# || |_) | (_| \__ \ __/ |__| (_) | | | | | | | __/ (__| |_| | (_) || | | || +# ||____/ \__,_|___/\___|\____\___/|_| |_|_| |_|\___|\___|\__|_|\___/ |_| |_|| +# | | +# +--------------------------------------------------------------------------+ +# | Abstract base class of SingleSiteConnection and MultiSiteConnection | +# '--------------------------------------------------------------------------' + +class BaseConnection: + def __init__(self, socketurl, persist = False, allow_cache = False): + """Create a new connection to a MK Livestatus socket""" + self.add_headers = "" + self.auth_header = "" + self.persist = persist + self.allow_cache = allow_cache + self.socketurl = socketurl + self.socket = None + self.timeout = None + self.successful_persistence = False + + def successfully_persisted(self): + return self.successful_persistence + + def add_header(self, header): + self.add_headers += header + "\n" + + def set_timeout(self, timeout): + self.timeout = timeout + if self.socket: + self.socket.settimeout(float(timeout)) + + def connect(self): + if self.persist and self.socketurl in persistent_connections: + self.socket = persistent_connections[self.socketurl] + self.successful_persistence = True + return + + self.successful_persistence = False + + # Create new socket + self.socket = None + url = self.socketurl + parts = url.split(":") + if parts[0] == "unix": + if len(parts) != 2: + raise MKLivestatusConfigError("Invalid livestatus unix URL: %s. " + "Correct example is 'unix:/var/run/nagios/rw/live'" % url) + self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + target = parts[1] + + elif parts[0] == "tcp": + try: + host = parts[1] + port = int(parts[2]) + except: + raise MKLivestatusConfigError("Invalid livestatus tcp URL '%s'. " + "Correct example is 'tcp:somehost:6557'" % url) + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + target = (host, port) + else: + raise MKLivestatusConfigError("Invalid livestatus URL '%s'. " + "Must begin with 'tcp:' or 'unix:'" % url) + + # If a timeout is set, then we retry after a failure with mild + # a binary backoff. + if self.timeout: + before = time.time() + sleep_interval = 0.1 + + while True: + try: + if self.timeout: + self.socket.settimeout(float(sleep_interval)) + self.socket.connect(target) + break + except Exception, e: + if self.timeout: + time_left = self.timeout - (time.time() - before) + # only try again, if there is substantial time left + if time_left > sleep_interval: + time.sleep(sleep_interval) + sleep_interval *= 1.5 + continue + + self.socket = None + raise MKLivestatusSocketError("Cannot connect to '%s': %s" % (self.socketurl, e)) + + if self.persist: + persistent_connections[self.socketurl] = self.socket + + def disconnect(self): + self.socket = None + if self.persist: + try: + del persistent_connections[self.socketurl] + except KeyError: + pass + + def receive_data(self, size): + result = b"" + # Timeout is only honored when connecting + self.socket.settimeout(None) + while size > 0: + packet = self.socket.recv(size) + if len(packet) == 0: + raise MKLivestatusSocketClosed("Read zero data from socket, nagios server closed connection") + size -= len(packet) + result += packet + return result + + def do_query(self, query, add_headers = ""): + self.send_query(query, add_headers) + return self.recv_response(query, add_headers) + + def send_query(self, query_obj, add_headers = "", do_reconnect=True): + orig_query = query_obj + + query = "%s" % query_obj + if not self.allow_cache: + query = remove_cache_regex.sub("", query) + + if self.socket == None: + self.connect() + + if not query.endswith("\n"): + query += "\n" + query += self.auth_header + self.add_headers + query += "Localtime: %d\nOutputFormat: python\nKeepAlive: on\nResponseHeader: fixed16\n" % int(time.time()) + query += add_headers + + if not query.endswith("\n"): + query += "\n" + query += "\n" + + try: + # socket.send() will implicitely cast to str(), we need ot + # convert to UTF-8 in order to avoid exceptions + if type(query) == unicode: + query = query.encode("utf-8") + self.socket.send(query) + except IOError, e: + if self.persist: + del persistent_connections[self.socketurl] + self.successful_persistence = False + self.socket = None + + if do_reconnect: + # Automatically try to reconnect in case of an error, but + # only once. + self.connect() + self.send_query(orig_query, add_headers, False) + return + + raise MKLivestatusSocketError("RC1:" + str(e)) + + # Reads a response from the livestatus socket. If the socket is closed + # by the livestatus server, we automatically make a reconnect and send + # the query again (once). This is due to timeouts during keepalive. + def recv_response(self, query = None, add_headers = "", timeout_at = None): + try: + # Headers are always ASCII encoded + resp = self.receive_data(16) + code = resp[0:3] + try: + length = int(resp[4:15].lstrip()) + except: + self.disconnect() + raise MKLivestatusSocketError("Malformed output. Livestatus TCP socket might be unreachable.") + + data = self.receive_data(length).decode("utf-8") + + if code == "200": + try: + return ast.literal_eval(data) + except: + self.disconnect() + raise MKLivestatusSocketError("Malformed output") + + elif code == "404": + raise MKLivestatusTableNotFoundError("Not Found (%s): %s" % (code, data.strip())) + + else: + raise MKLivestatusQueryError("%s: %s" % (code, data.strip())) + + except (MKLivestatusSocketClosed, IOError), e: + # In case of an IO error or the other side having + # closed the socket do a reconnect and try again + self.disconnect() + now = time.time() + if query and (not timeout_at or timeout_at > now): + if timeout_at == None: + # Try until timeout reached in case there was a timeout configured. + # Otherwise only retry once. + timeout_at = now + if self.timeout: + timeout_at += self.timeout + + time.sleep(0.1) + self.connect() + self.send_query(query, add_headers) + return self.recv_response(query, add_headers, timeout_at) # do not send query again -> danger of infinite loop + else: + raise MKLivestatusSocketError(str(e)) + + except MKLivestatusTableNotFoundError: + raise + + except Exception, e: + # Catches + # MKLivestatusQueryError + # MKLivestatusSocketError + # FIXME: ? self.disconnect() + raise MKLivestatusSocketError("Unhandled exception: %s" % e) + + + def do_command(self, command): + if self.socket == None: + self.connect() + if not command.endswith("\n"): + command += "\n" + try: + self.socket.send("COMMAND " + command + "\n") + except IOError, e: + self.socket = None + if self.persist: + del persistent_connections[self.socketurl] + raise MKLivestatusSocketError(str(e)) + + +#. +# .--SingleSiteConn------------------------------------------------------. +# | ____ _ _ ____ _ _ ____ | +# | / ___|(_)_ __ __ _| | ___/ ___|(_) |_ ___ / ___|___ _ __ _ __ | +# | \___ \| | '_ \ / _` | |/ _ \___ \| | __/ _ \ | / _ \| '_ \| '_ \ | +# | ___) | | | | | (_| | | __/___) | | || __/ |__| (_) | | | | | | | | +# | |____/|_|_| |_|\__, |_|\___|____/|_|\__\___|\____\___/|_| |_|_| |_| | +# | |___/ | +# +----------------------------------------------------------------------+ +# | Connections to one local Unix or remote TCP socket. | +# '----------------------------------------------------------------------' + +class SingleSiteConnection(BaseConnection, Helpers): + def __init__(self, socketurl, persist = False, allow_cache = False): + BaseConnection.__init__(self, socketurl, persist, allow_cache) + self.prepend_site = False + self.auth_users = {} + self.deadsites = {} # never filled, just for compatibility + self.limit = None + + def set_prepend_site(self, p): + self.prepend_site = p + + def set_only_sites(self, os = None): + pass + + def set_limit(self, limit = None): + self.limit = limit + + def query(self, query, add_headers = ""): + if self.limit != None: + query += "Limit: %d\n" % self.limit + data = self.do_query(query, add_headers) + if self.prepend_site: + return [ [''] + line for line in data ] + else: + return data + + def command(self, command, site = None): + self.do_command(command) + + # Set user to be used in certain authorization domain + def set_auth_user(self, domain, user): + if user: + self.auth_users[domain] = user + elif domain in self.auth_users: + del self.auth_users[domain] + + # Switch future request to new authorization domain + def set_auth_domain(self, domain): + auth_user = self.auth_users.get(domain) + if auth_user: + self.auth_header = "AuthUser: %s\n" % auth_user + else: + self.auth_header = "" + + +#. +# .--MultiSiteConn-------------------------------------------------------. +# | __ __ _ _ _ ____ _ _ ____ | +# | | \/ |_ _| | |_(_) ___|(_) |_ ___ / ___|___ _ __ _ __ | +# | | |\/| | | | | | __| \___ \| | __/ _ \ | / _ \| '_ \| '_ \ | +# | | | | | |_| | | |_| |___) | | || __/ |__| (_) | | | | | | | | +# | |_| |_|\__,_|_|\__|_|____/|_|\__\___|\____\___/|_| |_|_| |_| | +# | | +# +----------------------------------------------------------------------+ +# | Connections to a list of local and remote sites. | +# '----------------------------------------------------------------------' + +# sites is a dictionary from site name to a dict. +# Keys in the dictionary: +# socket: socketurl (obligatory) +# timeout: timeout for tcp/unix in seconds + +# TODO: Move the connect/disconnect stuff to separate methods. Then make +# it possible to connect/disconnect duing existance of a single object. + +class MultiSiteConnection(Helpers): + def __init__(self, sites, disabled_sites = None): + if disabled_sites is None: + disabled_sites = {} + + self.sites = sites + self.connections = [] + self.deadsites = {} + self.prepend_site = False + self.only_sites = None + self.limit = None + self.parallelize = True + + # Helper function for connecting to a site + def connect_to_site(sitename, site, temporary=False): + try: + url = site["socket"] + persist = not temporary and site.get("persist", False) + connection = SingleSiteConnection(url, persist, allow_cache=site.get("cache", False)) + if "timeout" in site: + connection.set_timeout(int(site["timeout"])) + connection.connect() + self.connections.append((sitename, site, connection)) + + except Exception, e: + self.deadsites[sitename] = { + "exception" : e, + "site" : site, + } + + # Needed for temporary connection for status_hosts in disabled sites + def disconnect_site(sitename): + i = 0 + for name, site, connection in self.connections: + if name == sitename: + del self.connections[i] + return + i += 1 + + + # Status host: A status host helps to prevent trying to connect + # to a remote site which is unreachable. This is done by looking + # at the current state of a certain host on a local site that is + # representing the connection to the remote site. The status host + # is specified as an optional pair of (site, host) in the entry + # "status_host". We first connect to all sites without a status_host + # entry, then retrieve the host states of the status hosts and then + # connect to the remote site which are reachable + + # Tackle very special problem: If the user disables a site which + # provides status_host information for other sites, the dead-detection + # would not work. For that cases we make a temporary connection just + # to fetch the status information + extra_status_sites = {} + if len(disabled_sites) > 0: + status_sitenames = set([]) + for sitename, site in sites.items(): + try: + s, h = site.get("status_host") + status_sitenames.add(s) + except: + continue + for sitename in status_sitenames: + site = disabled_sites.get(sitename) + if site: + extra_status_sites[sitename] = site + + + # First connect to sites without status host. Collect status + # hosts at the same time. + + status_hosts = {} # dict from site to list of status_hosts + for sitename, site in sites.items() + extra_status_sites.items(): + status_host = site.get("status_host") + if status_host: + if type(status_host) != tuple or len(status_host) != 2: + raise MKLivestatusConfigError("Status host of site %s is %r, but must be pair of site and host" % + (sitename, status_host)) + s, h = status_host + status_hosts[s] = status_hosts.get(s, []) + [h] + else: + connect_to_site(sitename, site) + + # Now learn current states of status hosts and store it in a dictionary + # from (local_site, host) => state + status_host_states = {} + for sitename, hosts in status_hosts.items(): + # Fetch all the states of status hosts of this local site in one query + query = "GET hosts\nColumns: name state has_been_checked last_time_up\n" + for host in hosts: + query += "Filter: name = %s\n" % host + query += "Or: %d\n" % len(hosts) + self.set_only_sites([sitename]) # only connect one site + try: + result = self.query_table(query) + # raise MKLivestatusConfigError("TRESulT: %s" % (result,)) + for host, state, has_been_checked, lastup in result: + if has_been_checked == 0: + state = 3 + status_host_states[(sitename, host)] = (state, lastup) + except Exception, e: + raise MKLivestatusConfigError(e) + status_host_states[(sitename, host)] = (str(e), None) + self.set_only_sites() # clear site filter + + # Disconnect from disabled sites that we connected to only to + # get status information from + for sitename, site in extra_status_sites.items(): + disconnect_site(sitename) + + # Now loop over all sites having a status_host and take that state + # of that into consideration + + for sitename, site in sites.items(): + status_host = site.get("status_host") + if status_host: + now = time.time() + shs, lastup = status_host_states.get(status_host, (4, now)) # None => Status host not existing + deltatime = now - lastup + if shs == 0 or shs == None: + connect_to_site(sitename, site) + else: + if shs == 1: + ex = "The remote monitoring host is down" + elif shs == 2: + ex = "The remote monitoring host is unreachable" + elif shs == 3: + ex = "The remote monitoring host's state it not yet determined" + elif shs == 4: + ex = "Invalid status host: site %s has no host %s" % (status_host[0], status_host[1]) + else: + ex = "Error determining state of remote monitoring host: %s" % shs + self.deadsites[sitename] = { + "site" : site, + "status_host_state" : shs, + "exception" : ex, + } + + def add_header(self, header): + for sitename, site, connection in self.connections: + connection.add_header(header) + + def set_prepend_site(self, p): + self.prepend_site = p + + def set_only_sites(self, sites=None): + """Make future queries only contact the given sites. + + Provide a list of site IDs to not contact all configured sites, but only the listed + site IDs. In case None is given, the limitation is removed. + """ + self.only_sites = sites + + # Impose Limit on number of returned datasets (distributed amoung sites) + def set_limit(self, limit = None): + self.limit = limit + + def dead_sites(self): + return self.deadsites + + def alive_sites(self): + return [ s[0] for s in self.connections ] + + def successfully_persisted(self): + for sitename, site, connection in self.connections: + if connection.successfully_persisted(): + return True + return False + + def set_auth_user(self, domain, user): + for sitename, site, connection in self.connections: + connection.set_auth_user(domain, user) + + def set_auth_domain(self, domain): + for sitename, site, connection in self.connections: + connection.set_auth_domain(domain) + + def query(self, query, add_headers = ""): + if self.parallelize: + return self.query_parallel(query, add_headers) + else: + return self.query_non_parallel(query, add_headers) + + def query_non_parallel(self, query, add_headers = ""): + result = [] + stillalive = [] + limit = self.limit + for sitename, site, connection in self.connections: + if self.only_sites != None and sitename not in self.only_sites: + stillalive.append( (sitename, site, connection) ) # state unknown, assume still alive + continue + try: + if limit != None: + limit_header = "Limit: %d\n" % limit + else: + limit_header = "" + r = connection.query(query, add_headers + limit_header) + if self.prepend_site: + r = [ [sitename] + l for l in r ] + if limit != None: + limit -= len(r) # Account for portion of limit used by this site + result += r + stillalive.append( (sitename, site, connection) ) + except Exception, e: + connection.disconnect() + self.deadsites[sitename] = { + "exception" : e, + "site" : site, + } + self.connections = stillalive + return result + + # New parallelized version of query(). The semantics differs in the handling + # of Limit: since all sites are queried in parallel, the Limit: is simply + # applied to all sites - resulting in possibly more results then Limit requests. + def query_parallel(self, query, add_headers = ""): + stillalive = [] + if self.only_sites != None: + connect_to_sites = [ c for c in self.connections if c[0] in self.only_sites ] + # Unused sites are assumed to be alive + stillalive.extend( [ c for c in self.connections if c[0] not in self.only_sites]) + else: + connect_to_sites = self.connections + + start_time = time.time() + limit = self.limit + if limit != None: + limit_header = "Limit: %d\n" % limit + else: + limit_header = "" + + # First send all queries + for sitename, site, connection in connect_to_sites: + try: + connection.send_query(query, add_headers + limit_header) + except Exception, e: + self.deadsites[sitename] = { + "exception" : e, + "site" : site, + } + + if isinstance(query, Query): + suppress_exceptions = tuple(query.suppress_exceptions) + else: + suppress_exceptions = tuple(Query.default_suppressed_exceptions) + + # Then retrieve all answers. We will be as slow as the slowest of all + # connections. + result = [] + for sitename, site, connection in connect_to_sites: + try: + r = connection.recv_response(query, add_headers + limit_header) + stillalive.append( (sitename, site, connection) ) + if self.prepend_site: + r = [ [sitename] + l for l in r ] + result += r + except suppress_exceptions: + stillalive.append( (sitename, site, connection) ) + continue + + except Exception, e: + connection.disconnect() + self.deadsites[sitename] = { + "exception" : e, + "site" : site, + } + + self.connections = stillalive + return result + + def command(self, command, sitename = "local"): + if sitename in self.deadsites: + raise MKLivestatusSocketError("Connection to site %s is dead: %s" % \ + (sitename, self.deadsites[sitename]["exception"])) + conn = [t[2] for t in self.connections if t[0] == sitename] + if len(conn) == 0: + raise MKLivestatusConfigError("Cannot send command to unconfigured site '%s'" % sitename) + conn[0].do_command(command) + + # Return connection to localhost (UNIX), if available + def local_connection(self): + for sitename, site, connection in self.connections: + if site["socket"].startswith("unix:") and "liveproxy" not in site["socket"]: + return connection + raise MKLivestatusConfigError("No livestatus connection to local host") + + + +#. +# .--LocalConn-----------------------------------------------------------. +# | _ _ ____ | +# | | | ___ ___ __ _| |/ ___|___ _ __ _ __ | +# | | | / _ \ / __/ _` | | | / _ \| '_ \| '_ \ | +# | | |__| (_) | (_| (_| | | |__| (_) | | | | | | | | +# | |_____\___/ \___\__,_|_|\____\___/|_| |_|_| |_| | +# | | +# +----------------------------------------------------------------------+ +# | LocalConnection is a convenciance class for connecting to the | +# | local Livestatus socket within an OMD site. It only works within | +# | OMD context. It immediately connects() | +# '----------------------------------------------------------------------' + +class LocalConnection(SingleSiteConnection): + def __init__(self, *args, **kwargs): + omd_root = os.getenv("OMD_ROOT") + if not omd_root: + raise MKLivestatusConfigError("OMD_ROOT is not set. You are not running in OMD context.") + SingleSiteConnection.__init__(self, "unix:" + omd_root + "/tmp/run/live", *args, **kwargs) + self.connect() diff --git a/api/python/make_nagvis_map.py b/api/python/make_nagvis_map.py new file mode 100755 index 0000000..aeb11fc --- /dev/null +++ b/api/python/make_nagvis_map.py @@ -0,0 +1,119 @@ +#!/usr/bin/python +# -*- encoding: utf-8; py-indent-offset: 4 -*- +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# This is an example for a usage of Livestatus: it creates +# a NagVis map using actual live data from a running Nagios +# system. Most things are hardcoded here but this might by +# a useful example for coding your own stuff... + +import livestatus + +g_y = 50 +y_title = 40 +lineheight = 30 +x_hostgroup = 30 +x_therm = 200 +x_usv = 560 + +def make_label(text, x, y, width): + print """ +define textbox { + text=%s + x=%d + y=%d + background_color=#C0C0C1 + border_color=#000055 + w=%d +}""" % (text, x, y, width) + + +def render_hostgroup(name, alias): + global g_y + g_y += lineheight + + # Name des Serverraums + make_label(alias, x_hostgroup, g_y, x_therm - x_hostgroup - 20) + def display_servicegroup(name, x): + if live.query_value("GET servicegroups\nStats: name = %s\n" % name) == 1: + print """ +define servicegroup { + servicegroup_name = %s + x=%d + y=%d +}""" % (name, x, g_y) + + # Einzelauflistung der Thermometer + num = 0 + shift = 16 + for host, service in live.query("GET services\nFilter: groups >= %s\nColumns: host_name description" % name): + num += 1 + print """ +define service { + host_name=%s + service_description=%s + x=%d + y=%d + url=/pnp4nagios/graph?host=%s&srv=%s +} + """ % (host, service, x + 30 + shift * num, g_y, host, service) + + # Gesamtzustand Thermometer + display_servicegroup(name + "_therm", x_therm) + + # Auflistung der USV-Parameter + display_servicegroup(name + "_usv", x_usv) + + + + +socket_path = "unix:/var/run/nagios/rw/live" +live = livestatus.SingleSiteConnection(socket_path) + +print """ +define global { + allowed_for_config=nagiosadmin + allowed_user=nagiosadmin + map_image=demo_background.png + iconset=std_medium +} +""" + + +# hostgroups = live.query("GET hostgroups\nColumns: name alias") +hostgroups = [ + ( "s02", "S-02" ), + ( "s06", "S-06" ), + ( "s48", "S-48" ), + ( "ad214", "AD-214" ), + ( "ik026", "IK-026" ), + ( "etage", "Etagenverteiler" ), + ] +for name, alias in hostgroups: + render_hostgroup(name, alias) + +make_label("Temperaturen", x_therm, y_title, 250) +make_label("USV-Status", x_usv, y_title, 160) + diff --git a/ar-lib b/ar-lib new file mode 100755 index 0000000..05094d3 --- /dev/null +++ b/ar-lib @@ -0,0 +1,270 @@ +#! /bin/sh +# Wrapper for Microsoft lib.exe + +me=ar-lib +scriptversion=2012-03-01.08; # UTC + +# Copyright (C) 2010-2017 Free Software Foundation, Inc. +# Written by Peter Rosin . +# +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + + +# func_error message +func_error () +{ + echo "$me: $1" 1>&2 + exit 1 +} + +file_conv= + +# func_file_conv build_file +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv in + mingw) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_at_file at_file operation archive +# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE +# for each of them. +# When interpreting the content of the @FILE, do NOT use func_file_conv, +# since the user would need to supply preconverted file names to +# binutils ar, at least for MinGW. +func_at_file () +{ + operation=$2 + archive=$3 + at_file_contents=`cat "$1"` + eval set x "$at_file_contents" + shift + + for member + do + $AR -NOLOGO $operation:"$member" "$archive" || exit $? + done +} + +case $1 in + '') + func_error "no command. Try '$0 --help' for more information." + ;; + -h | --h*) + cat <. +# +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..f50dcdb --- /dev/null +++ b/config.guess @@ -0,0 +1,1480 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-02-24' + +# This file 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 . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > "$dummy.c" ; + for c in cc gcc c89 c99 ; do + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval "$set_cc_for_build" + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval "$set_cc_for_build" + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos"$UNAME_RELEASE" + ;; + sun4) + echo sparc-sun-sunos"$UNAME_RELEASE" + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + then + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] + then + echo m88k-dg-dgux"$UNAME_RELEASE" + else + echo m88k-dg-dguxbcs"$UNAME_RELEASE" + fi + else + echo i586-dg-dgux"$UNAME_RELEASE" + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ "$HP_ARCH" = hppa2.0w ] + then + eval "$set_cc_for_build" + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + i*86:Minix:*:*) + echo "$UNAME_MACHINE"-pc-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + eval "$set_cc_for_build" + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + if objdump -f /bin/sh | grep -q elf32-x86-64; then + echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 + else + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + fi + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo "$UNAME_MACHINE"-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval "$set_cc_for_build" + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..bed54c6 --- /dev/null +++ b/config.h.in @@ -0,0 +1,226 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* we do not want any old stuff */ +#undef BOOST_SYSTEM_NO_DEPRECATED + +/* C++ compiler */ +#undef BUILD_CXX + +/* build date */ +#undef BUILD_DATE + +/* name of the build host */ +#undef BUILD_HOSTNAME + +/* Define to 1 if you have the `accept4' function. */ +#undef HAVE_ACCEPT4 + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* define if the Boost library is available */ +#undef HAVE_BOOST + +/* define if the Boost::ASIO library is available */ +#undef HAVE_BOOST_ASIO + +/* define if the compiler supports basic C++17 syntax */ +#undef HAVE_CXX17 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if RE2 should be used. */ +#undef HAVE_RE2 + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#undef HAVE_STAT_EMPTY_STRING_BUG + +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIMEB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to the type of arg 1 for `select'. */ +#undef SELECT_TYPE_ARG1 + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#undef SELECT_TYPE_ARG234 + +/* Define to the type of arg 5 for `select'. */ +#undef SELECT_TYPE_ARG5 + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* the maximum number of states the regex NFA can have */ +#undef _GLIBCXX_REGEX_STATE_LIMIT + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint64_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* we want C11 library extensions */ +#ifndef __STDC_WANT_LIB_EXT1__ +# define __STDC_WANT_LIB_EXT1__ 1 +#endif + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef int32_t + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to `int' if does not define. */ +#undef ssize_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..1d8e98b --- /dev/null +++ b/config.sub @@ -0,0 +1,1801 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-02-22' + +# This file 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 . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | wasm32 \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | wasm32-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-pc + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2*) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + x64) + basic_machine=x86_64-pc + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases that might get confused + # with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4*) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + pru-*) + os=-elf + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` + ;; +esac + +echo "$basic_machine$os" +exit + +# Local variables: +# eval: (add-hook 'write-file-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..cbf2d77 --- /dev/null +++ b/configure @@ -0,0 +1,10407 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for MK Livestatus 1.5.0p23. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: mk@mathias-kettner.de about your system, including any +$0: error possibly output before this message. Then install +$0: a modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='MK Livestatus' +PACKAGE_TARNAME='mk-livestatus' +PACKAGE_VERSION='1.5.0p23' +PACKAGE_STRING='MK Livestatus 1.5.0p23' +PACKAGE_BUGREPORT='mk@mathias-kettner.de' +PACKAGE_URL='' + +ac_unique_file="config.h.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +nagios_headers +LIBOBJS +RE2_LIBS +RE2_LDFLAGS +RE2_CPPFLAGS +CXXCPP +BOOST_ASIO_LIB +BOOST_LDFLAGS +BOOST_CPPFLAGS +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +EGREP +GREP +CPP +RRDLIB +ac_ct_AR +AR +RANLIB +HAVE_CXX17 +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_rrd_is_thread_safe +enable_dependency_tracking +with_boost +with_boost_libdir +with_boost_asio +with_re2 +with_nagios4 +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures MK Livestatus 1.5.0p23 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/mk-livestatus] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of MK Livestatus 1.5.0p23:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --disable-rrd-is-thread-safe + Use librrd_th instead of librrd + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-boost[=ARG] use Boost library from a standard location + (ARG=yes), from the specified location (ARG=), + or disable it (ARG=no) [ARG=yes] + --with-boost-libdir=LIB_DIR + Force given directory for boost libraries. Note that + this will override library path detection, so use + this parameter only if default library detection + fails and you know exactly where your boost + libraries are located. + --with-boost-asio[=special-lib] + use the ASIO library from boost - it is possible to + specify a certain library for the linker e.g. + --with-boost-asio=boost_system-gcc41-mt-1_34 + --with-re2[=ARG] use RE2 library from a standard location (ARG=yes), + from the specified location (ARG=), or disable + it (ARG=no) [ARG=no] + --with-nagios4 enabled compilation for nagios 4 + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +MK Livestatus configure 1.5.0p23 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------ ## +## Report this to mk@mathias-kettner.de ## +## ------------------------------------ ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------ ## +## Report this to mk@mathias-kettner.de ## +## ------------------------------------ ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 +$as_echo_n "checking for int$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_intX_t + +# ac_fn_c_find_uintX_t LINENO BITS VAR +# ------------------------------------ +# Finds an unsigned integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_uintX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 +$as_echo_n "checking for uint$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + case $ac_type in #( + uint$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_uintX_t + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by MK Livestatus $as_me 1.5.0p23, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +am__api_version='1.15' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='mk-livestatus' + VERSION='1.5.0p23' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + + +ac_config_headers="$ac_config_headers config.h" + + +cat >>confdefs.h <<_ACEOF +#define BUILD_DATE "`date -R`" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define BUILD_HOSTNAME "`uname -n`" +_ACEOF + + + + + +# Old (pre-1.6.0) versions of librrd were not thread-safe, so one has to use the +# thread-safe variant librrd_th explicitly. This in itself is already tragic +# enough, but to make things worse, you can't write a compile-time check to +# distinguish these versions. :-/ So we default to the assumption that librrd is +# thread-safe (which is the case within OMD) and the user of e.g. a standalone +# version of Livestatus on an old system has to use the configure flag below. +# Not really nice, but we can't really do much about that. +# Check whether --enable-rrd-is-thread-safe was given. +if test "${enable_rrd_is_thread_safe+set}" = set; then : + enableval=$enable_rrd_is_thread_safe; +fi + +if test "x$enable_rrd_is_thread_safe" != "xno"; then : + RRDLIB_TO_CHECK=rrd +else + RRDLIB_TO_CHECK=rrd_th +fi + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + for ac_prog in gcc-9 clang-8 gcc-8 clang-7 gcc-7 clang-6.0 clang-5.0 gcc clang + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in gcc-9 clang-8 gcc-8 clang-7 gcc-7 clang-6.0 clang-5.0 gcc clang +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +#include + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + +fi + + +if test "x$ac_cv_prog_cc_c99" = xno; then + as_fn_error $? "Need a C99-compliant C compiler" "$LINENO" 5 +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++-9 clang++-8 g++-8 clang++-7 g++-7 clang++-6.0 clang++-5.0 g++ clang++ + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++-9 clang++-8 g++-8 clang++-7 g++-7 clang++-6.0 clang++-5.0 g++ clang++ +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + +cat >>confdefs.h <<_ACEOF +#define BUILD_CXX "`$CXX --version | head -n1`" +_ACEOF + + + ax_cxx_compile_alternatives="17 1z" ax_cxx_compile_cxx17_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + ac_success=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++17 features by default... " >&6; } +if ${ax_cv_cxx_compile_cxx17+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus <= 201402L + +#error "This is not a C++17 compiler" + +#else + +#if defined(__clang__) + #define REALLY_CLANG +#else + #if defined(__GNUC__) + #define REALLY_GCC + #endif +#endif + +#include +#include +#include + +namespace cxx17 +{ + +#if !defined(REALLY_CLANG) + namespace test_constexpr_lambdas + { + + // TODO: test it with clang++ from git + + constexpr int foo = [](){return 42;}(); + + } +#endif // !defined(REALLY_CLANG) + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + +#if !defined(REALLY_CLANG) + namespace test_template_argument_deduction_for_class_templates + { + + // TODO: test it with clang++ from git + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } +#endif // !defined(REALLY_CLANG) + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + +#if !defined(REALLY_CLANG) + namespace test_structured_bindings + { + + // TODO: test it with clang++ from git + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } +#endif // !defined(REALLY_CLANG) + +#if !defined(REALLY_CLANG) + namespace test_exception_spec_type_system + { + + // TODO: test it with clang++ from git + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } +#endif // !defined(REALLY_CLANG) + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus <= 201402L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx17=yes +else + ax_cv_cxx_compile_cxx17=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx17" >&5 +$as_echo "$ax_cv_cxx_compile_cxx17" >&6; } + if test x$ax_cv_cxx_compile_cxx17 = xyes; then + ac_success=yes + fi + + + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++17 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + + + + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus <= 201402L + +#error "This is not a C++17 compiler" + +#else + +#if defined(__clang__) + #define REALLY_CLANG +#else + #if defined(__GNUC__) + #define REALLY_GCC + #endif +#endif + +#include +#include +#include + +namespace cxx17 +{ + +#if !defined(REALLY_CLANG) + namespace test_constexpr_lambdas + { + + // TODO: test it with clang++ from git + + constexpr int foo = [](){return 42;}(); + + } +#endif // !defined(REALLY_CLANG) + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + +#if !defined(REALLY_CLANG) + namespace test_template_argument_deduction_for_class_templates + { + + // TODO: test it with clang++ from git + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } +#endif // !defined(REALLY_CLANG) + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + +#if !defined(REALLY_CLANG) + namespace test_structured_bindings + { + + // TODO: test it with clang++ from git + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } +#endif // !defined(REALLY_CLANG) + +#if !defined(REALLY_CLANG) + namespace test_exception_spec_type_system + { + + // TODO: test it with clang++ from git + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } +#endif // !defined(REALLY_CLANG) + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus <= 201402L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx17_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++17 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX17=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++17 support was found" >&5 +$as_echo "$as_me: No compiler with C++17 support was found" >&6;} + else + HAVE_CXX17=1 + +$as_echo "#define HAVE_CXX17 1" >>confdefs.h + + fi + +# m4_if([17], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])]) + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it. :-P + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar lib "link -lib" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 +$as_echo_n "checking the archiver ($AR) interface... " >&6; } +if ${am_cv_ar_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + am_cv_ar_interface=ar + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int some_variable = 0; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 +$as_echo "$am_cv_ar_interface" >&6; } + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + as_fn_error $? "could not determine $AR interface" "$LINENO" 5 + ;; +esac + + +# Checks for libraries. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +$as_echo_n "checking for socket in -lsocket... " >&6; } +if ${ac_cv_lib_socket_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_socket=yes +else + ac_cv_lib_socket_socket=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 +$as_echo "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 +$as_echo_n "checking for connect in -lsocket... " >&6; } +if ${ac_cv_lib_socket_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char connect (); +int +main () +{ +return connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_connect=yes +else + ac_cv_lib_socket_connect=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 +$as_echo "$ac_cv_lib_socket_connect" >&6; } +if test "x$ac_cv_lib_socket_connect" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shutdown in -lsocket" >&5 +$as_echo_n "checking for shutdown in -lsocket... " >&6; } +if ${ac_cv_lib_socket_shutdown+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shutdown (); +int +main () +{ +return shutdown (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_shutdown=yes +else + ac_cv_lib_socket_shutdown=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_shutdown" >&5 +$as_echo "$ac_cv_lib_socket_shutdown" >&6; } +if test "x$ac_cv_lib_socket_shutdown" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +# Passing through the right RRD library is a bit tricky: We can't simply put +# -lrrd_th or -lrrd globally into LIBS. The problem is that our SUID programs +# icmpsender and icmpreceiver would be linked with that option, too, but because +# of security reasons the dynamic linker will ignore our LD_LIBRARY_PATH => no +# RRD library found or even the wrong one... :-/ +RRDLIB= +old_LIBS=$LIBS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing rrd_xport" >&5 +$as_echo_n "checking for library containing rrd_xport... " >&6; } +if ${ac_cv_search_rrd_xport+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char rrd_xport (); +int +main () +{ +return rrd_xport (); + ; + return 0; +} +_ACEOF +for ac_lib in '' $RRDLIB_TO_CHECK; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_rrd_xport=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_rrd_xport+:} false; then : + break +fi +done +if ${ac_cv_search_rrd_xport+:} false; then : + +else + ac_cv_search_rrd_xport=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_rrd_xport" >&5 +$as_echo "$ac_cv_search_rrd_xport" >&6; } +ac_res=$ac_cv_search_rrd_xport +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + test "$ac_cv_search_rrd_xport" = "none required" || RRDLIB="$ac_cv_search_rrd_xport" +else + as_fn_error $? "unable to find the rrd_xport function" "$LINENO" 5 +fi + +LIBS=$old_LIBS + + +# Checks for header files. +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 +$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } +if ${ac_cv_header_sys_wait_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_sys_wait_h=yes +else + ac_cv_header_sys_wait_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 +$as_echo "$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for C++ features +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + + +# Check whether --with-boost was given. +if test "${with_boost+set}" = set; then : + withval=$with_boost; + case $withval in #( + no) : + want_boost="no";_AX_BOOST_BASE_boost_path="" ;; #( + yes) : + want_boost="yes";_AX_BOOST_BASE_boost_path="" ;; #( + *) : + want_boost="yes";_AX_BOOST_BASE_boost_path="$withval" ;; +esac + +else + want_boost="yes" +fi + + + + +# Check whether --with-boost-libdir was given. +if test "${with_boost_libdir+set}" = set; then : + withval=$with_boost_libdir; + if test -d "$withval"; then : + _AX_BOOST_BASE_boost_lib_path="$withval" +else + as_fn_error $? "--with-boost-libdir expected directory name" "$LINENO" 5 +fi + +else + _AX_BOOST_BASE_boost_lib_path="" +fi + + +BOOST_LDFLAGS="" +BOOST_CPPFLAGS="" +if test "x$want_boost" = "xyes"; then : + + + if test "x" = "x"; then : + _AX_BOOST_BASE_TONUMERICVERSION_req="1.20.0" +else + _AX_BOOST_BASE_TONUMERICVERSION_req="" +fi + _AX_BOOST_BASE_TONUMERICVERSION_req_shorten=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([0-9]*\.[0-9]*\)'` + _AX_BOOST_BASE_TONUMERICVERSION_req_major=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([0-9]*\)'` + if test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_major" = "x"; then : + as_fn_error $? "You should at least specify libboost major version" "$LINENO" 5 +fi + _AX_BOOST_BASE_TONUMERICVERSION_req_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[0-9]*\.\([0-9]*\)'` + if test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_minor" = "x"; then : + _AX_BOOST_BASE_TONUMERICVERSION_req_minor="0" +fi + _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[0-9]*\.[0-9]*\.\([0-9]*\)'` + if test "X$_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor" = "X"; then : + _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor="0" +fi + _AX_BOOST_BASE_TONUMERICVERSION_RET=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req_major \* 100000 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_minor \* 100 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor` + WANT_BOOST_VERSION=$_AX_BOOST_BASE_TONUMERICVERSION_RET + + succeeded=no + + + + case ${host_cpu} in #( + x86_64) : + libsubdirs="lib64 libx32 lib lib64" ;; #( + ppc64|s390x|sparc64|aarch64|ppc64le) : + libsubdirs="lib64 lib lib64" ;; #( + *) : + libsubdirs="lib" + ;; +esac + + case ${host_cpu} in #( + i?86) : + multiarch_libsubdir="lib/i386-${host_os}" ;; #( + *) : + multiarch_libsubdir="lib/${host_cpu}-${host_os}" + ;; +esac + + if test "x$_AX_BOOST_BASE_boost_path" != "x"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >= ($WANT_BOOST_VERSION) includes in \"$_AX_BOOST_BASE_boost_path/include\"" >&5 +$as_echo_n "checking for boostlib >= ($WANT_BOOST_VERSION) includes in \"$_AX_BOOST_BASE_boost_path/include\"... " >&6; } + if test -d "$_AX_BOOST_BASE_boost_path/include" && test -r "$_AX_BOOST_BASE_boost_path/include"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include" + for _AX_BOOST_BASE_boost_path_tmp in $multiarch_libsubdir $libsubdirs; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >= ($WANT_BOOST_VERSION) lib path in \"$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp\"" >&5 +$as_echo_n "checking for boostlib >= ($WANT_BOOST_VERSION) lib path in \"$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp\"... " >&6; } + if test -d "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" && test -r "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" ; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"; + break; + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + done +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + +else + + if test X"$cross_compiling" = Xyes; then + search_libsubdirs=$multiarch_libsubdir + else + search_libsubdirs="$multiarch_libsubdir $libsubdirs" + fi + for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$_AX_BOOST_BASE_boost_path_tmp/include/boost" && test -r "$_AX_BOOST_BASE_boost_path_tmp/include/boost" ; then + for libsubdir in $search_libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path_tmp/include" + break; + fi + done + +fi + + if test "x$_AX_BOOST_BASE_boost_lib_path" != "x"; then : + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_lib_path" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >= ($WANT_BOOST_VERSION)" >&5 +$as_echo_n "checking for boostlib >= ($WANT_BOOST_VERSION)... " >&6; } + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +(void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($WANT_BOOST_VERSION))])); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + succeeded=yes + found_system=yes + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + if test "x$succeeded" != "xyes" ; then + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + BOOST_CPPFLAGS= + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + BOOST_LDFLAGS= + fi + _version=0 + if test -n "$_AX_BOOST_BASE_boost_path" ; then + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path"; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "x$V_CHECK" = "x1" ; then + _version=$_version_tmp + fi + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include/boost-$VERSION_UNDERSCORE" + done + if test -z "$BOOST_CPPFLAGS"; then + if test -d "$_AX_BOOST_BASE_boost_path/boost" && test -r "$_AX_BOOST_BASE_boost_path/boost"; then + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path" + fi + fi + if test -n "$BOOST_CPPFLAGS" && test -z "$BOOST_LDFLAGS"; then + for libsubdir in $libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$libsubdir" + fi + fi + else + if test "x$cross_compiling" != "xyes" ; then + for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local ; do + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path" ; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "x$V_CHECK" = "x1" ; then + _version=$_version_tmp + best_path=$_AX_BOOST_BASE_boost_path + fi + done + fi + done + + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + for libsubdir in $libsubdirs ; do + if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$best_path/$libsubdir" + fi + fi + + if test -n "$BOOST_ROOT" ; then + for libsubdir in $libsubdirs ; do + if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then + version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` + stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` + stage_version_shorten=`expr $stage_version : '\([0-9]*\.[0-9]*\)'` + V_CHECK=`expr $stage_version_shorten \>\= $_version` + if test "x$V_CHECK" = "x1" && test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: We will use a staged boost library from $BOOST_ROOT" >&5 +$as_echo "$as_me: We will use a staged boost library from $BOOST_ROOT" >&6;} + BOOST_CPPFLAGS="-I$BOOST_ROOT" + BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" + fi + fi + fi + fi + + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +(void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($WANT_BOOST_VERSION))])); + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + succeeded=yes + found_system=yes + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + fi + + if test "x$succeeded" != "xyes" ; then + if test "x$_version" = "x0" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: We could not detect the boost libraries (version or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation." >&5 +$as_echo "$as_me: We could not detect the boost libraries (version or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation." >&6;} + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Your boost libraries seems to old (version $_version)." >&5 +$as_echo "$as_me: Your boost libraries seems to old (version $_version)." >&6;} + fi + # execute ACTION-IF-NOT-FOUND (if present): + as_fn_error $? "Boost library not found or too old" "$LINENO" 5 + else + +$as_echo "#define HAVE_BOOST /**/" >>confdefs.h + + # execute ACTION-IF-FOUND (if present): + : + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + + +fi + + + + + +# Check whether --with-boost-asio was given. +if test "${with_boost_asio+set}" = set; then : + withval=$with_boost_asio; + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_asio_lib="" + else + want_boost="yes" + ax_boost_user_asio_lib="$withval" + fi + +else + want_boost="yes" + +fi + + + if test "x$want_boost" = "xyes"; then + + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the Boost::ASIO library is available" >&5 +$as_echo_n "checking whether the Boost::ASIO library is available... " >&6; } +if ${ax_cv_boost_asio+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include + +int +main () +{ + + + boost::asio::io_service io; + boost::system::error_code timer_result; + boost::asio::deadline_timer t(io); + t.cancel(); + io.run_one(); + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_boost_asio=yes +else + ax_cv_boost_asio=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_boost_asio" >&5 +$as_echo "$ax_cv_boost_asio" >&6; } + if test "x$ax_cv_boost_asio" = "xyes"; then + +$as_echo "#define HAVE_BOOST_ASIO /**/" >>confdefs.h + + BN=boost_system + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/[^\/]*//'` + # NOTE: The AC_LANG_PUSH/POP below is a local modification! Without it, AC_CHECK_LIB + # would use the C compiler for compilation and linking of C++ libraries, which is wrong + # in general: C++ compilers usually add some magic linking flags etc. behind the scenes. + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + if test "x$ax_boost_user_asio_lib" = "x"; then + for ax_lib in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.dylib* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_system.*\)\.a.*$;\1;' ` ; do + as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_main" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l$ax_lib" >&5 +$as_echo_n "checking for main in -l$ax_lib... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$ax_lib $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + BOOST_ASIO_LIB="-l$ax_lib" link_thread="yes" break +else + link_thread="no" +fi + + done + else + for ax_lib in $ax_boost_user_asio_lib $BN-$ax_boost_user_asio_lib; do + as_ac_Lib=`$as_echo "ac_cv_lib_$ax_lib''_main" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l$ax_lib" >&5 +$as_echo_n "checking for main in -l$ax_lib... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$ax_lib $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + BOOST_ASIO_LIB="-l$ax_lib" link_asio="yes" break +else + link_asio="no" +fi + + done + + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "x$ax_lib" = "x"; then + as_fn_error $? "Could not find a version of the library!" "$LINENO" 5 + fi + if test "x$link_asio" = "xno"; then + as_fn_error $? "Could not link against $ax_lib !" "$LINENO" 5 + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi + +if test "x$ax_cv_boost_asio" = xno; then + as_fn_error $? "Boost::ASIO library not found" "$LINENO" 5 +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++17 headers are supported by default" >&5 +$as_echo_n "checking whether C++17 headers are supported by default... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +std::shared_mutex sm + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CXX="$CXX -stdlib=libc++" + CXXCPP="$CXXCPP -stdlib=libc++" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++17 headers are supported with -stdlib=libc++" >&5 +$as_echo_n "checking whether C++17 headers are supported with -stdlib=libc++... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +std::shared_mutex sm + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "C++ headers are too old. Please install a newer g++/clang/libc++-dev package." "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +# RE2 stuff + +# Check whether --with-re2 was given. +if test "${with_re2+set}" = set; then : + withval=$with_re2; case $withval in #( + no) : + want_re2="no";_AX_RE2_BASE_re2_path="" ;; #( + yes) : + want_re2="yes";_AX_RE2_BASE_re2_path="" ;; #( + *) : + want_re2="yes";_AX_RE2_BASE_re2_path="$withval" ;; +esac +else + want_re2="no" +fi + +RE2_CPPFLAGS="" +RE2_LDFLAGS="" +RE2_LIBS="" +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +if test "x$want_re2" = "xyes"; then : + if test "x$_AX_RE2_BASE_re2_path" != x; then : + RE2_CPPFLAGS="-I$_AX_RE2_BASE_re2_path/include" + RE2_LDFLAGS="-L$_AX_RE2_BASE_re2_path/lib" +fi + RE2_LIBS="-lre2" + CPPFLAGS_SAVED=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $RE2_CPPFLAGS" + ac_fn_cxx_check_header_mongrel "$LINENO" "re2/re2.h" "ac_cv_header_re2_re2_h" "$ac_includes_default" +if test "x$ac_cv_header_re2_re2_h" = xyes; then : + +else + as_fn_error $? "could not find a working RE2 header" "$LINENO" 5 +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RE2 library" >&5 +$as_echo_n "checking for RE2 library... " >&6; } + LDFLAGS_SAVED=$LDFLAGS + LDFLAGS="$LDFLAGS $RE2_LDFLAGS" + LIBS_SAVED=$LIBS + LIBS="$LIBS $RE2_LIBS -pthread" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +RE2::FullMatch("hello", "e") + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "could not find a working RE2 library" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$LIBS_SAVED + LDFLAGS=$LDFLAGS_SAVED + CPPFLAGS=$CPPFLAGS_SAVED + +$as_echo "#define HAVE_RE2 1" >>confdefs.h + +fi + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +if ${ac_cv_header_stdbool_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #ifndef bool + "error: bool is not defined" + #endif + #ifndef false + "error: false is not defined" + #endif + #if false + "error: false is not 0" + #endif + #ifndef true + "error: true is not defined" + #endif + #if true != 1 + "error: true is not 1" + #endif + #ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" + #endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + /* See body of main program for 'e'. */ + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + bool e = &s; + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdbool_h=yes +else + ac_cv_header_stdbool_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } + ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +if test "x$ac_cv_type__Bool" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + + +if test $ac_cv_header_stdbool_h = yes; then + +$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" +case $ac_cv_c_int32_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int32_t $ac_cv_c_int32_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" +case $ac_cv_c_int64_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int64_t $ac_cv_c_int64_t +_ACEOF +;; +esac + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" +if test "x$ac_cv_type_ssize_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define ssize_t int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" +case $ac_cv_c_uint32_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT32_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint32_t $ac_cv_c_uint32_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" +case $ac_cv_c_uint64_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT64_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint64_t $ac_cv_c_uint64_t +_ACEOF +;; + esac + + +# Checks for library functions. +for ac_header in sys/select.h sys/socket.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for select" >&5 +$as_echo_n "checking types of arguments for select... " >&6; } +if ${ac_cv_func_select_args+:} false; then : + $as_echo_n "(cached) " >&6 +else + for ac_arg234 in 'fd_set *' 'int *' 'void *'; do + for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do + for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif + +int +main () +{ +extern int select ($ac_arg1, + $ac_arg234, $ac_arg234, $ac_arg234, + $ac_arg5); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + done +done +# Provide a safe default value. +: "${ac_cv_func_select_args=int,int *,struct timeval *}" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_select_args" >&5 +$as_echo "$ac_cv_func_select_args" >&6; } +ac_save_IFS=$IFS; IFS=',' +set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` +IFS=$ac_save_IFS +shift + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG1 $1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG234 ($2) +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SELECT_TYPE_ARG5 ($3) +_ACEOF + +rm -f conftest* + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if ${ac_cv_type_signal+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5 +$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; } +if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f conftest.sym conftest.file +echo >conftest.file +if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then + if test "$cross_compiling" = yes; then : + ac_cv_func_lstat_dereferences_slashed_symlink=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + /* Linux will dereference the symlink and fail, as required by POSIX. + That is better in the sense that it means we will not + have to compile and use the lstat wrapper. */ + return lstat ("conftest.sym/", &sbuf) == 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_lstat_dereferences_slashed_symlink=yes +else + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +else + # If the `ln -s' command failed, then we probably don't even + # have an lstat function. + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f conftest.sym conftest.file + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 +$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } + +test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && + +cat >>confdefs.h <<_ACEOF +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +_ACEOF + + +if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then + case " $LIBOBJS " in + *" lstat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; +esac + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5 +$as_echo_n "checking whether stat accepts an empty string... " >&6; } +if ${ac_cv_func_stat_empty_string_bug+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_stat_empty_string_bug=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + return stat ("", &sbuf) == 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_stat_empty_string_bug=no +else + ac_cv_func_stat_empty_string_bug=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5 +$as_echo "$ac_cv_func_stat_empty_string_bug" >&6; } +if test $ac_cv_func_stat_empty_string_bug = yes; then + case " $LIBOBJS " in + *" stat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS stat.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<_ACEOF +#define HAVE_STAT_EMPTY_STRING_BUG 1 +_ACEOF + +fi + +for ac_func in accept4 memmove select socket strerror strtoul +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +# Check whether --with-nagios4 was given. +if test "${with_nagios4+set}" = set; then : + withval=$with_nagios4; + CPPFLAGS="${CFLAGS} -DNAGIOS4" + nagios_headers=nagios4 + +else + nagios_headers=nagios +fi + + + +# Compiling or executing a std::regex can fail with a stack overflow, causing +# our Livestatus threads to die, see e.g. the related bug report +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582. A workaround for this is +# to limit the number of NFA states, but this must be done at compile-time. To +# be sure that the limit is defined before is included, we set it +# here. If the limit is reached during runtime, the regex library will throw a +# std::regex_error with a std::regex_constants::error_space code. This whole +# thing is a kind of a hack, but currently there seems to be no way around that, +# at least not until the libstdc++ uses heap allocated memory instead of the +# stack... :-/ +# +# Some numbers for x86_64: At the point where we compile or execute a regex, we +# already use almost 12kB stack. For compilation of a regex, each level of +# recursion uses additional 112 bytes. For executing a regex, each level of +# recursion uses additional 384 bytes. Our current stack size for the Livestatus +# threads is 1MB, so we can handle roughly 2700 states. To be on the safe side, +# we leave some breathing room and use a slightly lower limit. + +$as_echo "#define _GLIBCXX_REGEX_STATE_LIMIT 2500" >>confdefs.h + + + +$as_echo "#define BOOST_SYSTEM_NO_DEPRECATED 1" >>confdefs.h + + +# GCC is a bit picky about redefinitions of built-in macros. Alas, "built-in" +# simply means "starts with double underscore", so we have to hack around that +# below. Note that clang is happy, even without the guard. + + +# HACKING ALERT: automake can't really handle optional subdirectories, so we +# have to do this in a slightly hacky way by using M4's silent includes. + + +ac_config_files="$ac_config_files Makefile src/Makefile" + + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by MK Livestatus $as_me 1.5.0p23, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +MK Livestatus config.status 1.5.0p23 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..bc650f5 --- /dev/null +++ b/configure.ac @@ -0,0 +1,216 @@ +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT([MK Livestatus], [1.5.0p23], [mk@mathias-kettner.de]) +AM_INIT_AUTOMAKE([-Wall -Wno-portability foreign]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_SRCDIR([config.h.in]) +AC_CONFIG_HEADER([config.h]) +AC_DEFINE_UNQUOTED([BUILD_DATE], ["`date -R`"], [build date]) +AC_DEFINE_UNQUOTED([BUILD_HOSTNAME], ["`uname -n`"], [name of the build host]) +AC_REQUIRE_AUX_FILE([compile]) +AC_REQUIRE_AUX_FILE([config.guess]) +AC_REQUIRE_AUX_FILE([config.sub]) + +# Old (pre-1.6.0) versions of librrd were not thread-safe, so one has to use the +# thread-safe variant librrd_th explicitly. This in itself is already tragic +# enough, but to make things worse, you can't write a compile-time check to +# distinguish these versions. :-/ So we default to the assumption that librrd is +# thread-safe (which is the case within OMD) and the user of e.g. a standalone +# version of Livestatus on an old system has to use the configure flag below. +# Not really nice, but we can't really do much about that. +AC_ARG_ENABLE([rrd-is-thread-safe], + AS_HELP_STRING([--disable-rrd-is-thread-safe], [Use librrd_th instead of librrd])) +AS_IF([test "x$enable_rrd_is_thread_safe" != "xno"], [RRDLIB_TO_CHECK=rrd], + [RRDLIB_TO_CHECK=rrd_th]) + +# Checks for programs. +AC_PROG_CC([gcc-9 clang-8 gcc-8 clang-7 gcc-7 clang-6.0 clang-5.0 gcc clang]) +AC_PROG_CC_C99([], []) +if test "x$ac_cv_prog_cc_c99" = xno; then + AC_MSG_ERROR([Need a C99-compliant C compiler]) +fi +AC_PROG_CXX([g++-9 clang++-8 g++-8 clang++-7 g++-7 clang++-6.0 clang++-5.0 g++ clang++]) +AC_DEFINE_UNQUOTED([BUILD_CXX], ["`$CXX --version | head -n1`"], [C++ compiler]) +AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) +AC_PROG_RANLIB +# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it. :-P +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) + +# Checks for libraries. +AC_CHECK_LIB(socket, socket) +AC_CHECK_LIB(socket, connect) +AC_CHECK_LIB(socket, shutdown) + +# Passing through the right RRD library is a bit tricky: We can't simply put +# -lrrd_th or -lrrd globally into LIBS. The problem is that our SUID programs +# icmpsender and icmpreceiver would be linked with that option, too, but because +# of security reasons the dynamic linker will ignore our LD_LIBRARY_PATH => no +# RRD library found or even the wrong one... :-/ +RRDLIB= +old_LIBS=$LIBS +AC_SEARCH_LIBS([rrd_xport], [$RRDLIB_TO_CHECK], + [test "$ac_cv_search_rrd_xport" = "none required" || RRDLIB="$ac_cv_search_rrd_xport"], + [AC_MSG_ERROR([unable to find the rrd_xport function])]) +LIBS=$old_LIBS +AC_SUBST(RRDLIB) + +# Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h]) + +# Checks for C++ features +AX_BOOST_BASE(,,AC_MSG_ERROR([Boost library not found or too old])) +AX_BOOST_ASIO +if test "x$ax_cv_boost_asio" = xno; then + AC_MSG_ERROR([Boost::ASIO library not found]) +fi + +AC_LANG_PUSH([C++]) + +AC_MSG_CHECKING([whether C++17 headers are supported by default]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#include +#include ], [std::shared_mutex sm])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + CXX="$CXX -stdlib=libc++" + CXXCPP="$CXXCPP -stdlib=libc++" + AC_MSG_CHECKING([whether C++17 headers are supported with -stdlib=libc++]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#include +#include ], [std::shared_mutex sm])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([C++ headers are too old. Please install a newer g++/clang/libc++-dev package.])])]) + +# RE2 stuff +AC_ARG_WITH([re2], + [AS_HELP_STRING([--with-re2@<:@=ARG@:>@], + [use RE2 library from a standard location (ARG=yes), + from the specified location (ARG=), + or disable it (ARG=no) @<:@ARG=no@:>@ ])], + [AS_CASE([$withval], + [no],[want_re2="no";_AX_RE2_BASE_re2_path=""], + [yes],[want_re2="yes";_AX_RE2_BASE_re2_path=""], + [want_re2="yes";_AX_RE2_BASE_re2_path="$withval"])], + [want_re2="no"]) +RE2_CPPFLAGS="" +RE2_LDFLAGS="" +RE2_LIBS="" +AS_IF([test "x$want_re2" = "xyes"], + [AS_IF([test "x$_AX_RE2_BASE_re2_path" != x], + [RE2_CPPFLAGS="-I$_AX_RE2_BASE_re2_path/include" + RE2_LDFLAGS="-L$_AX_RE2_BASE_re2_path/lib"]) + RE2_LIBS="-lre2" + CPPFLAGS_SAVED=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $RE2_CPPFLAGS" + AC_CHECK_HEADER([re2/re2.h], [], [AC_MSG_ERROR([could not find a working RE2 header])]) + AC_MSG_CHECKING([for RE2 library]) + LDFLAGS_SAVED=$LDFLAGS + LDFLAGS="$LDFLAGS $RE2_LDFLAGS" + LIBS_SAVED=$LIBS + LIBS="$LIBS $RE2_LIBS -pthread" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[RE2::FullMatch("hello", "e")]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([could not find a working RE2 library])]) + LIBS=$LIBS_SAVED + LDFLAGS=$LDFLAGS_SAVED + CPPFLAGS=$CPPFLAGS_SAVED + AC_DEFINE([HAVE_RE2], [1], [Define to 1 if RE2 should be used.])]) +AC_SUBST(RE2_CPPFLAGS) +AC_SUBST(RE2_LDFLAGS) +AC_SUBST(RE2_LIBS) + +AC_LANG_POP([C++]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_HEADER_TIME +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T + +# Checks for library functions. +AC_FUNC_SELECT_ARGTYPES +AC_TYPE_SIGNAL +AC_FUNC_STAT +AC_CHECK_FUNCS([accept4 memmove select socket strerror strtoul]) + +AC_ARG_WITH(nagios4,AC_HELP_STRING([--with-nagios4],[enabled compilation for nagios 4]), [ + CPPFLAGS="${CFLAGS} -DNAGIOS4" + nagios_headers=nagios4 + ], + nagios_headers=nagios) +AC_SUBST(nagios_headers) + +# Compiling or executing a std::regex can fail with a stack overflow, causing +# our Livestatus threads to die, see e.g. the related bug report +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582. A workaround for this is +# to limit the number of NFA states, but this must be done at compile-time. To +# be sure that the limit is defined before is included, we set it +# here. If the limit is reached during runtime, the regex library will throw a +# std::regex_error with a std::regex_constants::error_space code. This whole +# thing is a kind of a hack, but currently there seems to be no way around that, +# at least not until the libstdc++ uses heap allocated memory instead of the +# stack... :-/ +# +# Some numbers for x86_64: At the point where we compile or execute a regex, we +# already use almost 12kB stack. For compilation of a regex, each level of +# recursion uses additional 112 bytes. For executing a regex, each level of +# recursion uses additional 384 bytes. Our current stack size for the Livestatus +# threads is 1MB, so we can handle roughly 2700 states. To be on the safe side, +# we leave some breathing room and use a slightly lower limit. +AC_DEFINE([_GLIBCXX_REGEX_STATE_LIMIT], [2500], + [the maximum number of states the regex NFA can have]) + +AC_DEFINE([BOOST_SYSTEM_NO_DEPRECATED], [1], [we do not want any old stuff]) + +# GCC is a bit picky about redefinitions of built-in macros. Alas, "built-in" +# simply means "starts with double underscore", so we have to hack around that +# below. Note that clang is happy, even without the guard. +AH_VERBATIM([__STDC_WANT_LIB_EXT1__], [/* we want C11 library extensions */ +#ifndef __STDC_WANT_LIB_EXT1__ +# define __STDC_WANT_LIB_EXT1__ 1 +#endif]) + +# HACKING ALERT: automake can't really handle optional subdirectories, so we +# have to do this in a slightly hacky way by using M4's silent includes. +m4_sinclude([livestatus/config_files.m4]) +m4_sinclude([enterprise/config_files.m4]) +m4_sinclude([standalone/config_files.m4]) + +AC_OUTPUT diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..b39f98f --- /dev/null +++ b/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2016-01-11.22; # UTC + +# Copyright (C) 1999-2017 Free Software Foundation, Inc. + +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..59990a1 --- /dev/null +++ b/install-sh @@ -0,0 +1,508 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2014-09-12.12; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # $RANDOM is not portable (e.g. dash); use it when possible to + # lower collision chance + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # As "mkdir -p" follows symlinks and we work in /tmp possibly; so + # create the $tmpdir first (and fail if unsuccessful) to make sure + # that nobody tries to guess the $tmpdir name. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/m4/ax_boost_asio.m4 b/m4/ax_boost_asio.m4 new file mode 100644 index 0000000..e18c3d1 --- /dev/null +++ b/m4/ax_boost_asio.m4 @@ -0,0 +1,115 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_boost_asio.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_ASIO +# +# DESCRIPTION +# +# Test for Asio library from the Boost C++ libraries. The macro requires a +# preceding call to AX_BOOST_BASE. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_ASIO_LIB) +# +# And sets: +# +# HAVE_BOOST_ASIO +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2008 Pete Greenwell +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 17 + +AC_DEFUN([AX_BOOST_ASIO], +[ + AC_ARG_WITH([boost-asio], + AS_HELP_STRING([--with-boost-asio@<:@=special-lib@:>@], + [use the ASIO library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-asio=boost_system-gcc41-mt-1_34 ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_asio_lib="" + else + want_boost="yes" + ax_boost_user_asio_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::ASIO library is available, + ax_cv_boost_asio, + [AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @%:@include + ]], + [[ + + boost::asio::io_service io; + boost::system::error_code timer_result; + boost::asio::deadline_timer t(io); + t.cancel(); + io.run_one(); + return 0; + ]])], + ax_cv_boost_asio=yes, ax_cv_boost_asio=no) + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_asio" = "xyes"; then + AC_DEFINE(HAVE_BOOST_ASIO,,[define if the Boost::ASIO library is available]) + BN=boost_system + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + # NOTE: The AC_LANG_PUSH/POP below is a local modification! Without it, AC_CHECK_LIB + # would use the C compiler for compilation and linking of C++ libraries, which is wrong + # in general: C++ compilers usually add some magic linking flags etc. behind the scenes. + AC_LANG_PUSH([C++]) + if test "x$ax_boost_user_asio_lib" = "x"; then + for ax_lib in `ls $BOOSTLIBDIR/libboost_system*.so* $BOOSTLIBDIR/libboost_system*.dylib* $BOOSTLIBDIR/libboost_system*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_system.*\)\.a.*$;\1;' ` ; do + AC_CHECK_LIB($ax_lib, main, [BOOST_ASIO_LIB="-l$ax_lib" AC_SUBST(BOOST_ASIO_LIB) link_thread="yes" break], + [link_thread="no"]) + done + else + for ax_lib in $ax_boost_user_asio_lib $BN-$ax_boost_user_asio_lib; do + AC_CHECK_LIB($ax_lib, main, + [BOOST_ASIO_LIB="-l$ax_lib" AC_SUBST(BOOST_ASIO_LIB) link_asio="yes" break], + [link_asio="no"]) + done + + fi + AC_LANG_POP([C++]) + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the library!) + fi + if test "x$link_asio" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/m4/ax_boost_base.m4 b/m4/ax_boost_base.m4 new file mode 100644 index 0000000..2bce519 --- /dev/null +++ b/m4/ax_boost_base.m4 @@ -0,0 +1,301 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_boost_base.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# DESCRIPTION +# +# Test for the Boost C++ libraries of a particular version (or newer) +# +# If no path to the installed boost library is given the macro searchs +# under /usr, /usr/local, /opt and /opt/local and evaluates the +# $BOOST_ROOT environment variable. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) +# +# And sets: +# +# HAVE_BOOST +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2009 Peter Adolphs +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 43 + +# example boost program (need to pass version) +m4_define([_AX_BOOST_BASE_PROGRAM], + [AC_LANG_PROGRAM([[ +#include +]],[[ +(void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($1))])); +]])]) + +AC_DEFUN([AX_BOOST_BASE], +[ +AC_ARG_WITH([boost], + [AS_HELP_STRING([--with-boost@<:@=ARG@:>@], + [use Boost library from a standard location (ARG=yes), + from the specified location (ARG=), + or disable it (ARG=no) + @<:@ARG=yes@:>@ ])], + [ + AS_CASE([$withval], + [no],[want_boost="no";_AX_BOOST_BASE_boost_path=""], + [yes],[want_boost="yes";_AX_BOOST_BASE_boost_path=""], + [want_boost="yes";_AX_BOOST_BASE_boost_path="$withval"]) + ], + [want_boost="yes"]) + + +AC_ARG_WITH([boost-libdir], + [AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. + Note that this will override library path detection, + so use this parameter only if default library detection fails + and you know exactly where your boost libraries are located.])], + [ + AS_IF([test -d "$withval"], + [_AX_BOOST_BASE_boost_lib_path="$withval"], + [AC_MSG_ERROR([--with-boost-libdir expected directory name])]) + ], + [_AX_BOOST_BASE_boost_lib_path=""]) + +BOOST_LDFLAGS="" +BOOST_CPPFLAGS="" +AS_IF([test "x$want_boost" = "xyes"], + [_AX_BOOST_BASE_RUNDETECT([$1],[$2],[$3])]) +AC_SUBST(BOOST_CPPFLAGS) +AC_SUBST(BOOST_LDFLAGS) +]) + + +# convert a version string in $2 to numeric and affect to polymorphic var $1 +AC_DEFUN([_AX_BOOST_BASE_TONUMERICVERSION],[ + AS_IF([test "x$2" = "x"],[_AX_BOOST_BASE_TONUMERICVERSION_req="1.20.0"],[_AX_BOOST_BASE_TONUMERICVERSION_req="$2"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_shorten=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\.[[0-9]]*\)'` + _AX_BOOST_BASE_TONUMERICVERSION_req_major=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_major" = "x"], + [AC_MSG_ERROR([You should at least specify libboost major version])]) + _AX_BOOST_BASE_TONUMERICVERSION_req_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_minor" = "x"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + AS_IF([test "X$_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor" = "X"], + [_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor="0"]) + _AX_BOOST_BASE_TONUMERICVERSION_RET=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req_major \* 100000 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_minor \* 100 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor` + AS_VAR_SET($1,$_AX_BOOST_BASE_TONUMERICVERSION_RET) +]) + +dnl Run the detection of boost should be run only if $want_boost +AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ + _AX_BOOST_BASE_TONUMERICVERSION(WANT_BOOST_VERSION,[$1]) + succeeded=no + + + AC_REQUIRE([AC_CANONICAL_HOST]) + dnl On 64-bit systems check for system libraries in both lib64 and lib. + dnl The former is specified by FHS, but e.g. Debian does not adhere to + dnl this (as it rises problems for generic multi-arch support). + dnl The last entry in the list is chosen by default when no libraries + dnl are found, e.g. when only header-only libraries are installed! + AS_CASE([${host_cpu}], + [x86_64],[libsubdirs="lib64 libx32 lib lib64"], + [ppc64|s390x|sparc64|aarch64|ppc64le],[libsubdirs="lib64 lib lib64"], + [libsubdirs="lib"] + ) + + dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give + dnl them priority over the other paths since, if libs are found there, they + dnl are almost assuredly the ones desired. + AS_CASE([${host_cpu}], + [i?86],[multiarch_libsubdir="lib/i386-${host_os}"], + [multiarch_libsubdir="lib/${host_cpu}-${host_os}"] + ) + + dnl first we check the system location for boost libraries + dnl this location ist chosen if boost libraries are installed with the --layout=system option + dnl or if you install boost with RPM + AS_IF([test "x$_AX_BOOST_BASE_boost_path" != "x"],[ + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) includes in "$_AX_BOOST_BASE_boost_path/include"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/include" && test -r "$_AX_BOOST_BASE_boost_path/include"],[ + AC_MSG_RESULT([yes]) + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include" + for _AX_BOOST_BASE_boost_path_tmp in $multiarch_libsubdir $libsubdirs; do + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION) lib path in "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"]) + AS_IF([test -d "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" && test -r "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" ],[ + AC_MSG_RESULT([yes]) + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"; + break; + ], + [AC_MSG_RESULT([no])]) + done],[ + AC_MSG_RESULT([no])]) + ],[ + if test X"$cross_compiling" = Xyes; then + search_libsubdirs=$multiarch_libsubdir + else + search_libsubdirs="$multiarch_libsubdir $libsubdirs" + fi + for _AX_BOOST_BASE_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$_AX_BOOST_BASE_boost_path_tmp/include/boost" && test -r "$_AX_BOOST_BASE_boost_path_tmp/include/boost" ; then + for libsubdir in $search_libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path_tmp/include" + break; + fi + done + ]) + + dnl overwrite ld flags if we have required special directory with + dnl --with-boost-libdir parameter + AS_IF([test "x$_AX_BOOST_BASE_boost_lib_path" != "x"], + [BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_lib_path"]) + + AC_MSG_CHECKING([for boostlib >= $1 ($WANT_BOOST_VERSION)]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_REQUIRE([AC_PROG_CXX]) + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + + + + dnl if we found no boost with system layout we search for boost libraries + dnl built and installed without the --layout=system option or for a staged(not installed) version + if test "x$succeeded" != "xyes" ; then + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + BOOST_CPPFLAGS= + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + BOOST_LDFLAGS= + fi + _version=0 + if test -n "$_AX_BOOST_BASE_boost_path" ; then + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path"; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "x$V_CHECK" = "x1" ; then + _version=$_version_tmp + fi + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include/boost-$VERSION_UNDERSCORE" + done + dnl if nothing found search for layout used in Windows distributions + if test -z "$BOOST_CPPFLAGS"; then + if test -d "$_AX_BOOST_BASE_boost_path/boost" && test -r "$_AX_BOOST_BASE_boost_path/boost"; then + BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path" + fi + fi + dnl if we found something and BOOST_LDFLAGS was unset before + dnl (because "$_AX_BOOST_BASE_boost_lib_path" = ""), set it here. + if test -n "$BOOST_CPPFLAGS" && test -z "$BOOST_LDFLAGS"; then + for libsubdir in $libsubdirs ; do + if ls "$_AX_BOOST_BASE_boost_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$libsubdir" + fi + fi + else + if test "x$cross_compiling" != "xyes" ; then + for _AX_BOOST_BASE_boost_path in /usr /usr/local /opt /opt/local ; do + if test -d "$_AX_BOOST_BASE_boost_path" && test -r "$_AX_BOOST_BASE_boost_path" ; then + for i in `ls -d $_AX_BOOST_BASE_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$_AX_BOOST_BASE_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "x$V_CHECK" = "x1" ; then + _version=$_version_tmp + best_path=$_AX_BOOST_BASE_boost_path + fi + done + fi + done + + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" + if test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + for libsubdir in $libsubdirs ; do + if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$best_path/$libsubdir" + fi + fi + + if test -n "$BOOST_ROOT" ; then + for libsubdir in $libsubdirs ; do + if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then + version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` + stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` + stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` + V_CHECK=`expr $stage_version_shorten \>\= $_version` + if test "x$V_CHECK" = "x1" && test -z "$_AX_BOOST_BASE_boost_lib_path" ; then + AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) + BOOST_CPPFLAGS="-I$BOOST_ROOT" + BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" + fi + fi + fi + fi + + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([_AX_BOOST_BASE_PROGRAM($WANT_BOOST_VERSION)],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + fi + + if test "x$succeeded" != "xyes" ; then + if test "x$_version" = "x0" ; then + AC_MSG_NOTICE([[We could not detect the boost libraries (version $1 or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) + else + AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) + fi + # execute ACTION-IF-NOT-FOUND (if present): + ifelse([$3], , :, [$3]) + else + AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) + # execute ACTION-IF-FOUND (if present): + ifelse([$2], , :, [$2]) + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + +]) diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 0000000..eac609f --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,982 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016 Krzesimir Nowak +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AX_REQUIRE_DEFINED([AC_MSG_WARN]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +# m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])]) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus <= 201402L + +#error "This is not a C++17 compiler" + +#else + +#if defined(__clang__) + #define REALLY_CLANG +#else + #if defined(__GNUC__) + #define REALLY_GCC + #endif +#endif + +#include +#include +#include + +namespace cxx17 +{ + +#if !defined(REALLY_CLANG) + namespace test_constexpr_lambdas + { + + // TODO: test it with clang++ from git + + constexpr int foo = [](){return 42;}(); + + } +#endif // !defined(REALLY_CLANG) + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + +#if !defined(REALLY_CLANG) + namespace test_template_argument_deduction_for_class_templates + { + + // TODO: test it with clang++ from git + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } +#endif // !defined(REALLY_CLANG) + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + +#if !defined(REALLY_CLANG) + namespace test_structured_bindings + { + + // TODO: test it with clang++ from git + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } +#endif // !defined(REALLY_CLANG) + +#if !defined(REALLY_CLANG) + namespace test_exception_spec_type_system + { + + // TODO: test it with clang++ from git + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } +#endif // !defined(REALLY_CLANG) + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus <= 201402L + +]]) diff --git a/missing b/missing new file mode 100755 index 0000000..f62bbae --- /dev/null +++ b/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/nagios/README b/nagios/README new file mode 100644 index 0000000..9f02110 --- /dev/null +++ b/nagios/README @@ -0,0 +1,2 @@ +These files are taken directly from Nagios 3.2.0 with a minimal patch +that fixes one compilation error on g++. diff --git a/nagios/broker.h b/nagios/broker.h new file mode 100644 index 0000000..f334825 --- /dev/null +++ b/nagios/broker.h @@ -0,0 +1,223 @@ + +/***************************************************************************** + * + * BROKER.H - Event broker includes for Nagios + * + * Copyright (c) 2002-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-12-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _BROKER_H +#define _BROKER_H + +#include "config.h" +#include "nagios.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/*************** EVENT BROKER OPTIONS *****************/ + +#define BROKER_NOTHING 0 +#define BROKER_EVERYTHING 1048575 + +#define BROKER_PROGRAM_STATE 1 /* DONE */ +#define BROKER_TIMED_EVENTS 2 /* DONE */ +#define BROKER_SERVICE_CHECKS 4 /* DONE */ +#define BROKER_HOST_CHECKS 8 /* DONE */ +#define BROKER_EVENT_HANDLERS 16 /* DONE */ +#define BROKER_LOGGED_DATA 32 /* DONE */ +#define BROKER_NOTIFICATIONS 64 /* DONE */ +#define BROKER_FLAPPING_DATA 128 /* DONE */ +#define BROKER_COMMENT_DATA 256 /* DONE */ +#define BROKER_DOWNTIME_DATA 512 /* DONE */ +#define BROKER_SYSTEM_COMMANDS 1024 /* DONE */ +#define BROKER_OCP_DATA 2048 /* DONE */ +#define BROKER_STATUS_DATA 4096 /* DONE */ +#define BROKER_ADAPTIVE_DATA 8192 /* DONE */ +#define BROKER_EXTERNALCOMMAND_DATA 16384 /* DONE */ +#define BROKER_RETENTION_DATA 32768 /* DONE */ +#define BROKER_ACKNOWLEDGEMENT_DATA 65536 +#define BROKER_STATECHANGE_DATA 131072 +#define BROKER_RESERVED18 262144 +#define BROKER_RESERVED19 524288 + + +/****** EVENT TYPES ************************/ + +#define NEBTYPE_NONE 0 + +#define NEBTYPE_HELLO 1 +#define NEBTYPE_GOODBYE 2 +#define NEBTYPE_INFO 3 + +#define NEBTYPE_PROCESS_START 100 +#define NEBTYPE_PROCESS_DAEMONIZE 101 +#define NEBTYPE_PROCESS_RESTART 102 +#define NEBTYPE_PROCESS_SHUTDOWN 103 +#define NEBTYPE_PROCESS_PRELAUNCH 104 /* before objects are read or verified */ +#define NEBTYPE_PROCESS_EVENTLOOPSTART 105 +#define NEBTYPE_PROCESS_EVENTLOOPEND 106 + +#define NEBTYPE_TIMEDEVENT_ADD 200 +#define NEBTYPE_TIMEDEVENT_REMOVE 201 +#define NEBTYPE_TIMEDEVENT_EXECUTE 202 +#define NEBTYPE_TIMEDEVENT_DELAY 203 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SKIP 204 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SLEEP 205 + +#define NEBTYPE_LOG_DATA 300 +#define NEBTYPE_LOG_ROTATION 301 + +#define NEBTYPE_SYSTEM_COMMAND_START 400 +#define NEBTYPE_SYSTEM_COMMAND_END 401 + +#define NEBTYPE_EVENTHANDLER_START 500 +#define NEBTYPE_EVENTHANDLER_END 501 + +#define NEBTYPE_NOTIFICATION_START 600 +#define NEBTYPE_NOTIFICATION_END 601 +#define NEBTYPE_CONTACTNOTIFICATION_START 602 +#define NEBTYPE_CONTACTNOTIFICATION_END 603 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_START 604 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_END 605 + +#define NEBTYPE_SERVICECHECK_INITIATE 700 +#define NEBTYPE_SERVICECHECK_PROCESSED 701 +#define NEBTYPE_SERVICECHECK_RAW_START 702 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_RAW_END 703 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_ASYNC_PRECHECK 704 + +#define NEBTYPE_HOSTCHECK_INITIATE 800 /* a check of the route to the host has been initiated */ +#define NEBTYPE_HOSTCHECK_PROCESSED 801 /* the processed/final result of a host check */ +#define NEBTYPE_HOSTCHECK_RAW_START 802 /* the start of a "raw" host check */ +#define NEBTYPE_HOSTCHECK_RAW_END 803 /* a finished "raw" host check */ +#define NEBTYPE_HOSTCHECK_ASYNC_PRECHECK 804 +#define NEBTYPE_HOSTCHECK_SYNC_PRECHECK 805 + +#define NEBTYPE_COMMENT_ADD 900 +#define NEBTYPE_COMMENT_DELETE 901 +#define NEBTYPE_COMMENT_LOAD 902 + +#define NEBTYPE_FLAPPING_START 1000 +#define NEBTYPE_FLAPPING_STOP 1001 + +#define NEBTYPE_DOWNTIME_ADD 1100 +#define NEBTYPE_DOWNTIME_DELETE 1101 +#define NEBTYPE_DOWNTIME_LOAD 1102 +#define NEBTYPE_DOWNTIME_START 1103 +#define NEBTYPE_DOWNTIME_STOP 1104 + +#define NEBTYPE_PROGRAMSTATUS_UPDATE 1200 +#define NEBTYPE_HOSTSTATUS_UPDATE 1201 +#define NEBTYPE_SERVICESTATUS_UPDATE 1202 +#define NEBTYPE_CONTACTSTATUS_UPDATE 1203 + +#define NEBTYPE_ADAPTIVEPROGRAM_UPDATE 1300 +#define NEBTYPE_ADAPTIVEHOST_UPDATE 1301 +#define NEBTYPE_ADAPTIVESERVICE_UPDATE 1302 +#define NEBTYPE_ADAPTIVECONTACT_UPDATE 1303 + +#define NEBTYPE_EXTERNALCOMMAND_START 1400 +#define NEBTYPE_EXTERNALCOMMAND_END 1401 + +#define NEBTYPE_AGGREGATEDSTATUS_STARTDUMP 1500 +#define NEBTYPE_AGGREGATEDSTATUS_ENDDUMP 1501 + +#define NEBTYPE_RETENTIONDATA_STARTLOAD 1600 +#define NEBTYPE_RETENTIONDATA_ENDLOAD 1601 +#define NEBTYPE_RETENTIONDATA_STARTSAVE 1602 +#define NEBTYPE_RETENTIONDATA_ENDSAVE 1603 + +#define NEBTYPE_ACKNOWLEDGEMENT_ADD 1700 +#define NEBTYPE_ACKNOWLEDGEMENT_REMOVE 1701 /* NOT IMPLEMENTED */ +#define NEBTYPE_ACKNOWLEDGEMENT_LOAD 1702 /* NOT IMPLEMENTED */ + +#define NEBTYPE_STATECHANGE_START 1800 /* NOT IMPLEMENTED */ +#define NEBTYPE_STATECHANGE_END 1801 + + + +/****** EVENT FLAGS ************************/ + +#define NEBFLAG_NONE 0 +#define NEBFLAG_PROCESS_INITIATED 1 /* event was initiated by Nagios process */ +#define NEBFLAG_USER_INITIATED 2 /* event was initiated by a user request */ +#define NEBFLAG_MODULE_INITIATED 3 /* event was initiated by an event broker module */ + + + + +/****** EVENT ATTRIBUTES *******************/ + +#define NEBATTR_NONE 0 + +#define NEBATTR_SHUTDOWN_NORMAL 1 +#define NEBATTR_SHUTDOWN_ABNORMAL 2 +#define NEBATTR_RESTART_NORMAL 4 +#define NEBATTR_RESTART_ABNORMAL 8 + +#define NEBATTR_FLAPPING_STOP_NORMAL 1 +#define NEBATTR_FLAPPING_STOP_DISABLED 2 /* flapping stopped because flap detection was disabled */ + +#define NEBATTR_DOWNTIME_STOP_NORMAL 1 +#define NEBATTR_DOWNTIME_STOP_CANCELLED 2 + + + +/****** EVENT BROKER FUNCTIONS *************/ + +#ifdef USE_EVENT_BROKER +struct timeval get_broker_timestamp(struct timeval *); +void broker_program_state(int,int,int,struct timeval *); +void broker_timed_event(int,int,int,timed_event *,struct timeval *); +void broker_log_data(int,int,int,char *,unsigned long,time_t,struct timeval *); +void broker_event_handler(int,int,int,int,void *,int,int,struct timeval,struct timeval,double,int,int,int,char *,char *,char *,struct timeval *); +void broker_ocp_data(int,int,int,void *,int,int,double,int,int,struct timeval *); +void broker_system_command(int,int,int,struct timeval,struct timeval,double,int,int,int,char *,char *,struct timeval *); +int broker_host_check(int,int,int,host *,int,int,int,struct timeval,struct timeval,char *,double,double,int,int,int,char *,char *,char *,char *,struct timeval *); +int broker_service_check(int,int,int,service *,int,struct timeval,struct timeval,char *,double,double,int,int,int,char *,struct timeval *); +void broker_comment_data(int,int,int,int,int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long,struct timeval *); +void broker_downtime_data(int,int,int,int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long,struct timeval *); +void broker_flapping_data(int,int,int,int,void *,double,double,double,struct timeval *); +void broker_program_status(int,int,int,struct timeval *); +void broker_host_status(int,int,int,host *,struct timeval *); +void broker_service_status(int,int,int,service *,struct timeval *); +void broker_contact_status(int,int,int,contact *,struct timeval *); +void broker_notification_data(int,int,int,int,int,struct timeval,struct timeval,void *,char *,char *,int,int,struct timeval *); +void broker_contact_notification_data(int,int,int,int,int,struct timeval,struct timeval,void *,contact *,char *,char *,int,struct timeval *); +void broker_contact_notification_method_data(int,int,int,int,int,struct timeval,struct timeval,void *,contact *,char *,char *,char *,int,struct timeval *); +void broker_adaptive_program_data(int,int,int,int,unsigned long,unsigned long,unsigned long,unsigned long,struct timeval *); +void broker_adaptive_host_data(int,int,int,host *,int,unsigned long,unsigned long,struct timeval *); +void broker_adaptive_service_data(int,int,int,service *,int,unsigned long,unsigned long,struct timeval *); +void broker_adaptive_contact_data(int,int,int,contact *,int,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long, struct timeval *); +void broker_external_command(int,int,int,int,time_t,char *,char *,struct timeval *); +void broker_aggregated_status_data(int,int,int,struct timeval *); +void broker_retention_data(int,int,int,struct timeval *); +void broker_acknowledgement_data(int,int,int,int,void *,char *,char *,int,int,int,struct timeval *); +void broker_statechange_data(int,int,int,int,void *,int,int,int,int,struct timeval *); +#endif + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/cgiauth.h b/nagios/cgiauth.h new file mode 100644 index 0000000..1386421 --- /dev/null +++ b/nagios/cgiauth.h @@ -0,0 +1,74 @@ + +/***************************************************************************** + * + * CGIAUTH.H - Authorization utilities header file + * + * Last Modified: 11-24-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _AUTH_H +#define _AUTH_H + +#include "common.h" +#include "objects.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct authdata_struct{ + char *username; + int authorized_for_all_hosts; + int authorized_for_all_host_commands; + int authorized_for_all_services; + int authorized_for_all_service_commands; + int authorized_for_system_information; + int authorized_for_system_commands; + int authorized_for_configuration_information; + int authorized_for_read_only; + int authenticated; + }authdata; + + + +int get_authentication_information(authdata *); /* gets current authentication information */ + +int is_authorized_for_host(host *,authdata *); +int is_authorized_for_service(service *,authdata *); + +int is_authorized_for_all_hosts(authdata *); +int is_authorized_for_all_services(authdata *); + +int is_authorized_for_system_information(authdata *); +int is_authorized_for_system_commands(authdata *); +int is_authorized_for_host_commands(host *,authdata *); +int is_authorized_for_service_commands(service *,authdata *); + +int is_authorized_for_hostgroup(hostgroup *,authdata *); +int is_authorized_for_servicegroup(servicegroup *,authdata *); + +int is_authorized_for_configuration_information(authdata *); + +int is_authorized_for_read_only(authdata *); +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/cgiutils.h b/nagios/cgiutils.h new file mode 100644 index 0000000..f14e4f7 --- /dev/null +++ b/nagios/cgiutils.h @@ -0,0 +1,533 @@ + +/* include/cgiutils.h. Generated by configure. */ +/************************************************************************ + * + * CGIUTILS.H - Header file for common CGI functions + * Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-15-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _CGIUTILS_H +#define _CGIUTILS_H + +#include "objects.h" +#include "cgiauth.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* should we compile and use the statusmap CGI? */ +#define USE_STATUSMAP 1 +/* should we compile and use the statuswrl CGI? */ +#define USE_STATUSWRL 1 +/* should we compile and use the trends CGI? */ +#define USE_TRENDS 1 +/* should we compile and use the histogram CGI? */ +#define USE_HISTOGRAM 1 + + +/**************************** CGI REFRESH RATE ******************************/ + +#define DEFAULT_REFRESH_RATE 60 /* 60 second refresh rate for CGIs */ + + +/******************************* CGI NAMES **********************************/ + +#define STATUS_CGI "status.cgi" +#define STATUSMAP_CGI "statusmap.cgi" +#define STATUSWORLD_CGI "statuswrl.cgi" +#define COMMAND_CGI "cmd.cgi" +#define EXTINFO_CGI "extinfo.cgi" +#define SHOWLOG_CGI "showlog.cgi" +#define NOTIFICATIONS_CGI "notifications.cgi" +#define HISTORY_CGI "history.cgi" +#define CONFIG_CGI "config.cgi" +#define OUTAGES_CGI "outages.cgi" +#define TRENDS_CGI "trends.cgi" +#define AVAIL_CGI "avail.cgi" +#define TAC_CGI "tac.cgi" +#define STATUSWML_CGI "statuswml.cgi" +#define TRACEROUTE_CGI "traceroute.cgi" +#define HISTOGRAM_CGI "histogram.cgi" +#define CHECKSANITY_CGI "checksanity.cgi" +#define MINISTATUS_CGI "ministatus.cgi" +#define SUMMARY_CGI "summary.cgi" + + +/**************************** STYLE SHEET NAMES ******************************/ + +#define COMMON_CSS "common.css" + +#define SHOWLOG_CSS "showlog.css" +#define STATUS_CSS "status.css" +#define STATUSMAP_CSS "statusmap.css" +#define COMMAND_CSS "cmd.css" +#define EXTINFO_CSS "extinfo.css" +#define NOTIFICATIONS_CSS "notifications.css" +#define HISTORY_CSS "history.css" +#define CONFIG_CSS "config.css" +#define OUTAGES_CSS "outages.css" +#define TRENDS_CSS "trends.css" +#define AVAIL_CSS "avail.css" +#define TAC_CSS "tac.css" +#define HISTOGRAM_CSS "histogram.css" +#define CHECKSANITY_CSS "checksanity.css" +#define MINISTATUS_CSS "ministatus.css" +#define SUMMARY_CSS "summary.css" + + +/********************************* ICONS ************************************/ + +#define STATUS_ICON_WIDTH 20 +#define STATUS_ICON_HEIGHT 20 + +#define INFO_ICON "info.png" +#define INFO_ICON_ALT "Informational Message" +#define START_ICON "start.gif" +#define START_ICON_ALT "Program Start" +#define STOP_ICON "stop.gif" +#define STOP_ICON_ALT "Program End" +#define RESTART_ICON "restart.gif" +#define RESTART_ICON_ALT "Program Restart" +#define OK_ICON "recovery.png" +#define OK_ICON_ALT "Service Ok" +#define CRITICAL_ICON "critical.png" +#define CRITICAL_ICON_ALT "Service Critical" +#define WARNING_ICON "warning.png" +#define WARNING_ICON_ALT "Service Warning" +#define UNKNOWN_ICON "unknown.png" +#define UNKNOWN_ICON_ALT "Service Unknown" +#define NOTIFICATION_ICON "notify.gif" +#define NOTIFICATION_ICON_ALT "Service Notification" +#define LOG_ROTATION_ICON "logrotate.png" +#define LOG_ROTATION_ICON_ALT "Log Rotation" +#define EXTERNAL_COMMAND_ICON "command.png" +#define EXTERNAL_COMMAND_ICON_ALT "External Command" + +#define STATUS_DETAIL_ICON "status2.gif" +#define STATUS_OVERVIEW_ICON "status.gif" +#define STATUSMAP_ICON "status3.gif" +#define STATUSWORLD_ICON "status4.gif" +#define EXTINFO_ICON "extinfo.gif" +#define HISTORY_ICON "history.gif" +#define CONTACTGROUP_ICON "contactgroup.gif" +#define TRENDS_ICON "trends.gif" + +#define DISABLED_ICON "disabled.gif" +#define ENABLED_ICON "enabled.gif" +#define PASSIVE_ONLY_ICON "passiveonly.gif" +#define NOTIFICATIONS_DISABLED_ICON "ndisabled.gif" +#define ACKNOWLEDGEMENT_ICON "ack.gif" +#define REMOVE_ACKNOWLEDGEMENT_ICON "noack.gif" +#define COMMENT_ICON "comment.gif" +#define DELETE_ICON "delete.gif" +#define DELAY_ICON "delay.gif" +#define DOWNTIME_ICON "downtime.gif" +#define PASSIVE_ICON "passiveonly.gif" +#define RIGHT_ARROW_ICON "right.gif" +#define LEFT_ARROW_ICON "left.gif" +#define UP_ARROW_ICON "up.gif" +#define DOWN_ARROW_ICON "down.gif" +#define FLAPPING_ICON "flapping.gif" +#define SCHEDULED_DOWNTIME_ICON "downtime.gif" +#define EMPTY_ICON "empty.gif" + +#define ACTIVE_ICON "active.gif" +#define ACTIVE_ICON_ALT "Active Mode" +#define STANDBY_ICON "standby.gif" +#define STANDBY_ICON_ALT "Standby Mode" + +#define HOST_DOWN_ICON "critical.png" +#define HOST_DOWN_ICON_ALT "Host Down" +#define HOST_UNREACHABLE_ICON "critical.png" +#define HOST_UNREACHABLE_ICON_ALT "Host Unreachable" +#define HOST_UP_ICON "recovery.png" +#define HOST_UP_ICON_ALT "Host Up" +#define HOST_NOTIFICATION_ICON "notify.gif" +#define HOST_NOTIFICATION_ICON_ALT "Host Notification" + +#define SERVICE_EVENT_ICON "serviceevent.gif" +#define SERVICE_EVENT_ICON_ALT "Service Event Handler" +#define HOST_EVENT_ICON "hostevent.gif" +#define HOST_EVENT_ICON_ALT "Host Event Handler" + +#define THERM_OK_IMAGE "thermok.png" +#define THERM_WARNING_IMAGE "thermwarn.png" +#define THERM_CRITICAL_IMAGE "thermcrit.png" + +#define CONFIGURATION_ICON "config.gif" +#define NOTES_ICON "notes.gif" +#define ACTION_ICON "action.gif" +#define DETAIL_ICON "detail.gif" + +#define PARENT_TRAVERSAL_ICON "parentup.gif" + +#define TAC_DISABLED_ICON "tacdisabled.png" +#define TAC_ENABLED_ICON "tacenabled.png" + +#define ZOOM1_ICON "zoom1.gif" +#define ZOOM2_ICON "zoom2.gif" + +#define CONTEXT_HELP_ICON1 "contexthelp1.gif" +#define CONTEXT_HELP_ICON2 "contexthelp2.gif" + +#define SPLUNK_SMALL_WHITE_ICON "splunk1.gif" +#define SPLUNK_SMALL_BLACK_ICON "splunk2.gif" + + + +/************************** PLUGIN RETURN VALUES ****************************/ + +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN 3 /* changed from -1 on 02/24/2001 */ + + +/********************* EXTENDED INFO CGI DISPLAY TYPES *********************/ + +#define DISPLAY_PROCESS_INFO 0 +#define DISPLAY_HOST_INFO 1 +#define DISPLAY_SERVICE_INFO 2 +#define DISPLAY_COMMENTS 3 +#define DISPLAY_PERFORMANCE 4 +#define DISPLAY_HOSTGROUP_INFO 5 +#define DISPLAY_DOWNTIME 6 +#define DISPLAY_SCHEDULING_QUEUE 7 +#define DISPLAY_SERVICEGROUP_INFO 8 + + +/************************ COMMAND CGI COMMAND MODES *************************/ + +#define CMDMODE_NONE 0 +#define CMDMODE_REQUEST 1 +#define CMDMODE_COMMIT 2 + + + +/******************** HOST AND SERVICE NOTIFICATION TYPES ******************/ + +#define NOTIFICATION_ALL 0 /* all service and host notifications */ +#define NOTIFICATION_SERVICE_ALL 1 /* all types of service notifications */ +#define NOTIFICATION_HOST_ALL 2 /* all types of host notifications */ +#define NOTIFICATION_SERVICE_WARNING 4 +#define NOTIFICATION_SERVICE_UNKNOWN 8 +#define NOTIFICATION_SERVICE_CRITICAL 16 +#define NOTIFICATION_SERVICE_RECOVERY 32 +#define NOTIFICATION_HOST_DOWN 64 +#define NOTIFICATION_HOST_UNREACHABLE 128 +#define NOTIFICATION_HOST_RECOVERY 256 +#define NOTIFICATION_SERVICE_ACK 512 +#define NOTIFICATION_HOST_ACK 1024 +#define NOTIFICATION_SERVICE_FLAP 2048 +#define NOTIFICATION_HOST_FLAP 4096 +#define NOTIFICATION_SERVICE_CUSTOM 8192 +#define NOTIFICATION_HOST_CUSTOM 16384 + + +/********************** HOST AND SERVICE ALERT TYPES **********************/ + +#define HISTORY_ALL 0 /* all service and host alert */ +#define HISTORY_SERVICE_ALL 1 /* all types of service alerts */ +#define HISTORY_HOST_ALL 2 /* all types of host alerts */ +#define HISTORY_SERVICE_WARNING 4 +#define HISTORY_SERVICE_UNKNOWN 8 +#define HISTORY_SERVICE_CRITICAL 16 +#define HISTORY_SERVICE_RECOVERY 32 +#define HISTORY_HOST_DOWN 64 +#define HISTORY_HOST_UNREACHABLE 128 +#define HISTORY_HOST_RECOVERY 256 + + +/****************************** SORT TYPES *******************************/ + +#define SORT_NONE 0 +#define SORT_ASCENDING 1 +#define SORT_DESCENDING 2 + + +/***************************** SORT OPTIONS ******************************/ + +#define SORT_NOTHING 0 +#define SORT_HOSTNAME 1 +#define SORT_SERVICENAME 2 +#define SORT_SERVICESTATUS 3 +#define SORT_LASTCHECKTIME 4 +#define SORT_CURRENTATTEMPT 5 +#define SORT_STATEDURATION 6 +#define SORT_NEXTCHECKTIME 7 +#define SORT_HOSTSTATUS 8 + + +/****************** HOST AND SERVICE FILTER PROPERTIES *******************/ + +#define HOST_SCHEDULED_DOWNTIME 1 +#define HOST_NO_SCHEDULED_DOWNTIME 2 +#define HOST_STATE_ACKNOWLEDGED 4 +#define HOST_STATE_UNACKNOWLEDGED 8 +#define HOST_CHECKS_DISABLED 16 +#define HOST_CHECKS_ENABLED 32 +#define HOST_EVENT_HANDLER_DISABLED 64 +#define HOST_EVENT_HANDLER_ENABLED 128 +#define HOST_FLAP_DETECTION_DISABLED 256 +#define HOST_FLAP_DETECTION_ENABLED 512 +#define HOST_IS_FLAPPING 1024 +#define HOST_IS_NOT_FLAPPING 2048 +#define HOST_NOTIFICATIONS_DISABLED 4096 +#define HOST_NOTIFICATIONS_ENABLED 8192 +#define HOST_PASSIVE_CHECKS_DISABLED 16384 +#define HOST_PASSIVE_CHECKS_ENABLED 32768 +#define HOST_PASSIVE_CHECK 65536 +#define HOST_ACTIVE_CHECK 131072 +#define HOST_HARD_STATE 262144 +#define HOST_SOFT_STATE 524288 + + +#define SERVICE_SCHEDULED_DOWNTIME 1 +#define SERVICE_NO_SCHEDULED_DOWNTIME 2 +#define SERVICE_STATE_ACKNOWLEDGED 4 +#define SERVICE_STATE_UNACKNOWLEDGED 8 +#define SERVICE_CHECKS_DISABLED 16 +#define SERVICE_CHECKS_ENABLED 32 +#define SERVICE_EVENT_HANDLER_DISABLED 64 +#define SERVICE_EVENT_HANDLER_ENABLED 128 +#define SERVICE_FLAP_DETECTION_ENABLED 256 +#define SERVICE_FLAP_DETECTION_DISABLED 512 +#define SERVICE_IS_FLAPPING 1024 +#define SERVICE_IS_NOT_FLAPPING 2048 +#define SERVICE_NOTIFICATIONS_DISABLED 4096 +#define SERVICE_NOTIFICATIONS_ENABLED 8192 +#define SERVICE_PASSIVE_CHECKS_DISABLED 16384 +#define SERVICE_PASSIVE_CHECKS_ENABLED 32768 +#define SERVICE_PASSIVE_CHECK 65536 +#define SERVICE_ACTIVE_CHECK 131072 +#define SERVICE_HARD_STATE 262144 +#define SERVICE_SOFT_STATE 524288 + + +/****************************** SSI TYPES ********************************/ + +#define SSI_HEADER 0 +#define SSI_FOOTER 1 + + + +/************************ CONTEXT-SENSITIVE HELP *************************/ + +#define CONTEXTHELP_STATUS_DETAIL "A1" +#define CONTEXTHELP_STATUS_HGOVERVIEW "A2" +#define CONTEXTHELP_STATUS_HGSUMMARY "A3" +#define CONTEXTHELP_STATUS_HGGRID "A4" +#define CONTEXTHELP_STATUS_SVCPROBLEMS "A5" +#define CONTEXTHELP_STATUS_HOST_DETAIL "A6" +#define CONTEXTHELP_STATUS_HOSTPROBLEMS "A7" +#define CONTEXTHELP_STATUS_SGOVERVIEW "A8" +#define CONTEXTHELP_STATUS_SGSUMMARY "A9" +#define CONTEXTHELP_STATUS_SGGRID "A10" + +#define CONTEXTHELP_TAC "B1" + +#define CONTEXTHELP_MAP "C1" + +#define CONTEXTHELP_LOG "D1" + +#define CONTEXTHELP_HISTORY "E1" + +#define CONTEXTHELP_NOTIFICATIONS "F1" + +#define CONTEXTHELP_TRENDS_MENU1 "G1" +#define CONTEXTHELP_TRENDS_MENU2 "G2" +#define CONTEXTHELP_TRENDS_MENU3 "G3" +#define CONTEXTHELP_TRENDS_MENU4 "G4" +#define CONTEXTHELP_TRENDS_HOST "G5" +#define CONTEXTHELP_TRENDS_SERVICE "G6" + +#define CONTEXTHELP_AVAIL_MENU1 "H1" +#define CONTEXTHELP_AVAIL_MENU2 "H2" +#define CONTEXTHELP_AVAIL_MENU3 "H3" +#define CONTEXTHELP_AVAIL_MENU4 "H4" +#define CONTEXTHELP_AVAIL_MENU5 "H5" +#define CONTEXTHELP_AVAIL_HOSTGROUP "H6" +#define CONTEXTHELP_AVAIL_HOST "H7" +#define CONTEXTHELP_AVAIL_SERVICE "H8" +#define CONTEXTHELP_AVAIL_SERVICEGROUP "H9" + +#define CONTEXTHELP_EXT_HOST "I1" +#define CONTEXTHELP_EXT_SERVICE "I2" +#define CONTEXTHELP_EXT_HOSTGROUP "I3" +#define CONTEXTHELP_EXT_PROCESS "I4" +#define CONTEXTHELP_EXT_PERFORMANCE "I5" +#define CONTEXTHELP_EXT_COMMENTS "I6" +#define CONTEXTHELP_EXT_DOWNTIME "I7" +#define CONTEXTHELP_EXT_QUEUE "I8" +#define CONTEXTHELP_EXT_SERVICEGROUP "I9" + +#define CONTEXTHELP_CMD_INPUT "J1" +#define CONTEXTHELP_CMD_COMMIT "J2" + +#define CONTEXTHELP_OUTAGES "K1" + +#define CONTEXTHELP_CONFIG_MENU "L1" +#define CONTEXTHELP_CONFIG_HOSTS "L2" +#define CONTEXTHELP_CONFIG_HOSTDEPENDENCIES "L3" +#define CONTEXTHELP_CONFIG_HOSTESCALATIONS "L4" +#define CONTEXTHELP_CONFIG_HOSTGROUPS "L5" +#define CONTEXTHELP_CONFIG_HOSTGROUPESCALATIONS "L6" +#define CONTEXTHELP_CONFIG_SERVICES "L7" +#define CONTEXTHELP_CONFIG_SERVICEDEPENDENCIES "L8" +#define CONTEXTHELP_CONFIG_SERVICEESCALATIONS "L9" +#define CONTEXTHELP_CONFIG_CONTACTS "L10" +#define CONTEXTHELP_CONFIG_CONTACTGROUPS "L11" +#define CONTEXTHELP_CONFIG_TIMEPERIODS "L12" +#define CONTEXTHELP_CONFIG_COMMANDS "L13" +#define CONTEXTHELP_CONFIG_HOSTEXTINFO "L14" +#define CONTEXTHELP_CONFIG_SERVICEEXTINFO "L15" +#define CONTEXTHELP_CONFIG_SERVICEGROUPS "L16" + +#define CONTEXTHELP_HISTOGRAM_MENU1 "M1" +#define CONTEXTHELP_HISTOGRAM_MENU2 "M2" +#define CONTEXTHELP_HISTOGRAM_MENU3 "M3" +#define CONTEXTHELP_HISTOGRAM_MENU4 "M4" +#define CONTEXTHELP_HISTOGRAM_HOST "M5" +#define CONTEXTHELP_HISTOGRAM_SERVICE "M6" + +#define CONTEXTHELP_SUMMARY_MENU "N1" +#define CONTEXTHELP_SUMMARY_RECENT_ALERTS "N2" +#define CONTEXTHELP_SUMMARY_ALERT_TOTALS "N3" +#define CONTEXTHELP_SUMMARY_HOSTGROUP_ALERT_TOTALS "N4" +#define CONTEXTHELP_SUMMARY_HOST_ALERT_TOTALS "N5" +#define CONTEXTHELP_SUMMARY_SERVICE_ALERT_TOTALS "N6" +#define CONTEXTHELP_SUMMARY_ALERT_PRODUCERS "N7" +#define CONTEXTHELP_SUMMARY_SERVICEGROUP_ALERT_TOTALS "N8" + + +/************************** LIFO RETURN CODES ****************************/ + +#define LIFO_OK 0 +#define LIFO_ERROR_MEMORY 1 +#define LIFO_ERROR_FILE 2 +#define LIFO_ERROR_DATA 3 + + + + + +/*************************** DATA STRUCTURES *****************************/ + +/* LIFO data structure */ +typedef struct lifo_struct{ + char *data; + struct lifo_struct *next; + }lifo; + + +/* MMAPFILE structure - used for reading files via mmap() */ +typedef struct mmapfile_struct{ + char *path; + int mode; + int fd; + unsigned long file_size; + unsigned long current_position; + unsigned long current_line; + void *mmap_buf; + }mmapfile; + + + +/******************************** FUNCTIONS *******************************/ + +void reset_cgi_vars(void); +void free_cgi_vars(void); +void free_memory(void); + +char * get_cgi_config_location(void); /* gets location of the CGI config file to read */ +char * get_cmd_file_location(void); /* gets location of external command file to write to */ + +int read_cgi_config_file(char *); +int read_main_config_file(char *); +int read_all_object_configuration_data(char *,int); +int read_all_status_data(char *,int); + +int hashfunc(const char *name1, const char *name2, int hashslots); +int compare_hashdata(const char *,const char *,const char *,const char *); + +void strip(char *); /* strips newlines, carriage returns, and spaces from end of buffer */ +char *unescape_newlines(char *); +void sanitize_plugin_output(char *); /* strips HTML and bad characters from plugin output */ +void strip_html_brackets(char *); /* strips > and < from string */ +int process_macros(char *,char **,int); /* processes macros in a string */ + +void get_time_string(time_t *,char *,int,int); /* gets a date/time string */ +void get_datetime_string(time_t *,char *,int,int); +void get_interval_time_string(double,char *,int); /* gets a time string for an interval of time */ +void get_expire_time_string(time_t *,char *,int); /* gets a date/time string in the format used for Expire: tags*/ + +char * my_strtok(char *,char *); /* replacement for strtok() function - doesn't skip multiple tokens */ +char * my_strsep (char **, const char *); +#ifdef REMOVED_10182007 +int my_free(void **); /* my wrapper for free() */ +#endif + +char * url_encode(char *); /* encodes a string in proper URL format */ +char * html_encode(char *,int); /* encodes a string in HTML format (for what the user sees) */ +char * escape_string(char *); /* escape string for html form usage */ + +void get_time_breakdown(unsigned long,int *,int *,int *,int *); /* given total seconds, get days, hours, minutes, seconds */ + +void get_log_archive_to_use(int,char *,int); /* determines the name of the log archive to use */ +void determine_log_rotation_times(int); +int determine_archive_to_use_from_time(time_t); + +void print_extra_hostgroup_url(char *,char *); +void print_extra_servicegroup_url(char *,char *); + +void display_info_table(char *,int,authdata *); +void display_nav_table(char *,int); + +void display_splunk_host_url(host *); +void display_splunk_service_url(service *); +void display_splunk_generic_url(char *,int); +void strip_splunk_query_terms(char *); + +void include_ssi_files(char *,int); /* include user-defined SSI footers/headers */ +void include_ssi_file(char *); /* include user-defined SSI footer/header */ + +void cgi_config_file_error(char *); +void main_config_file_error(char *); +void object_data_error(void); +void status_data_error(void); + +void display_context_help(char *); /* displays context-sensitive help window */ + +int read_file_into_lifo(char *); /* LIFO functions */ +void free_lifo_memory(void); +int push_lifo(char *); +char *pop_lifo(void); + +mmapfile *mmap_fopen(char *); /* open a file read-only using mmap() */ +int mmap_fclose(mmapfile *); +char *mmap_fgets(mmapfile *); +char *mmap_fgets_multiline(mmapfile *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nagios/comments.h b/nagios/comments.h new file mode 100644 index 0000000..dea4360 --- /dev/null +++ b/nagios/comments.h @@ -0,0 +1,128 @@ + +/***************************************************************************** + * + * COMMENTS.H - Header file for comment functions + * + * Copyright (c) 1999-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-26-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _COMMENTS_H +#define _COMMENTS_H + +#include "config.h" +#include "common.h" +#include "objects.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +/**************************** COMMENT SOURCES ******************************/ + +#define COMMENTSOURCE_INTERNAL 0 +#define COMMENTSOURCE_EXTERNAL 1 + + + +/***************************** COMMENT TYPES *******************************/ + +#define HOST_COMMENT 1 +#define SERVICE_COMMENT 2 + + +/****************************** ENTRY TYPES ********************************/ + +#define USER_COMMENT 1 +#define DOWNTIME_COMMENT 2 +#define FLAPPING_COMMENT 3 +#define ACKNOWLEDGEMENT_COMMENT 4 + + +/*************************** CHAINED HASH LIMITS ***************************/ + +#define COMMENT_HASHSLOTS 1024 + + + +/**************************** DATA STRUCTURES ******************************/ + + +/* COMMENT structure */ +typedef struct comment_struct{ + int comment_type; + int entry_type; + unsigned long comment_id; + int source; + int persistent; + time_t entry_time; + int expires; + time_t expire_time; + char *host_name; + char *service_description; + char *author; + char *comment_data; + struct comment_struct *next; + struct comment_struct *nexthash; + }comment; + + +#ifdef NSCORE +int initialize_comment_data(char *); /* initializes comment data */ +int cleanup_comment_data(char *); /* cleans up comment data */ +int add_new_comment(int,int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); /* adds a new host or service comment */ +int add_new_host_comment(int,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); /* adds a new host comment */ +int add_new_service_comment(int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long *); /* adds a new service comment */ +int delete_comment(int,unsigned long); /* deletes a host or service comment */ +int delete_host_comment(unsigned long); /* deletes a host comment */ +int delete_service_comment(unsigned long); /* deletes a service comment */ +int delete_all_comments(int,char *,char *); /* deletes all comments for a particular host or service */ +int delete_all_host_comments(char *); /* deletes all comments for a specific host */ +int delete_host_acknowledgement_comments(host *); /* deletes all non-persistent ack comments for a specific host */ +int delete_all_service_comments(char *,char *); /* deletes all comments for a specific service */ +int delete_service_acknowledgement_comments(service *); /* deletes all non-persistent ack comments for a specific service */ + +int check_for_expired_comment(unsigned long); /* expires a comment */ +#endif + +comment *find_comment(unsigned long,int); /* finds a specific comment */ +comment *find_service_comment(unsigned long); /* finds a specific service comment */ +comment *find_host_comment(unsigned long); /* finds a specific host comment */ + +comment *get_first_comment_by_host(char *); +comment *get_next_comment_by_host(char *,comment *); + +int number_of_host_comments(char *); /* returns the number of comments associated with a particular host */ +int number_of_service_comments(char *, char *); /* returns the number of comments associated with a particular service */ + +int add_comment(int,int,char *,char *,time_t,char *,char *,unsigned long,int,int,time_t,int); /* adds a comment (host or service) */ +int add_host_comment(int,char *,time_t,char *,char *,unsigned long,int,int,time_t,int); /* adds a host comment */ +int add_service_comment(int,char *,char *,time_t,char *,char *,unsigned long,int,int,time_t,int); /* adds a service comment */ + +int add_comment_to_hashlist(comment *); + +void free_comment_data(void); /* frees memory allocated to the comment list */ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/common.h b/nagios/common.h new file mode 100644 index 0000000..c4d565f --- /dev/null +++ b/nagios/common.h @@ -0,0 +1,501 @@ + +/************************************************************************ + * + * Nagios Common Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-22-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + + +#define PROGRAM_VERSION "3.2.0" +#define PROGRAM_MODIFICATION_DATE "08-12-2009" + +/*#define DEBUG_CHECK_IPC 1 */ +/*#define DEBUG_CHECK_IPC2 1*/ + + + +/* daemon is thread safe */ +#ifdef NSCORE +#ifndef _REENTRANT +#define _REENTRANT +#endif +#ifndef _THREAD_SAFE +#define _THREAD_SAFE +#endif +#endif + +/* Experimental performance tweaks - use with caution */ +#undef USE_MEMORY_PERFORMANCE_TWEAKS + +/* my_free has been freed from bondage as a function */ +#define my_free(ptr) { if(ptr) { free(ptr); ptr = NULL; } } + + + +/***************************** COMMANDS *********************************/ + +#define CMD_NONE 0 + +#define CMD_ADD_HOST_COMMENT 1 +#define CMD_DEL_HOST_COMMENT 2 + +#define CMD_ADD_SVC_COMMENT 3 +#define CMD_DEL_SVC_COMMENT 4 + +#define CMD_ENABLE_SVC_CHECK 5 +#define CMD_DISABLE_SVC_CHECK 6 + +#define CMD_SCHEDULE_SVC_CHECK 7 + +#define CMD_DELAY_SVC_NOTIFICATION 9 + +#define CMD_DELAY_HOST_NOTIFICATION 10 + +#define CMD_DISABLE_NOTIFICATIONS 11 +#define CMD_ENABLE_NOTIFICATIONS 12 + +#define CMD_RESTART_PROCESS 13 +#define CMD_SHUTDOWN_PROCESS 14 + +#define CMD_ENABLE_HOST_SVC_CHECKS 15 +#define CMD_DISABLE_HOST_SVC_CHECKS 16 + +#define CMD_SCHEDULE_HOST_SVC_CHECKS 17 + +#define CMD_DELAY_HOST_SVC_NOTIFICATIONS 19 /* currently unimplemented */ + +#define CMD_DEL_ALL_HOST_COMMENTS 20 +#define CMD_DEL_ALL_SVC_COMMENTS 21 + +#define CMD_ENABLE_SVC_NOTIFICATIONS 22 +#define CMD_DISABLE_SVC_NOTIFICATIONS 23 +#define CMD_ENABLE_HOST_NOTIFICATIONS 24 +#define CMD_DISABLE_HOST_NOTIFICATIONS 25 +#define CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST 26 +#define CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST 27 +#define CMD_ENABLE_HOST_SVC_NOTIFICATIONS 28 +#define CMD_DISABLE_HOST_SVC_NOTIFICATIONS 29 + +#define CMD_PROCESS_SERVICE_CHECK_RESULT 30 + +#define CMD_SAVE_STATE_INFORMATION 31 +#define CMD_READ_STATE_INFORMATION 32 + +#define CMD_ACKNOWLEDGE_HOST_PROBLEM 33 +#define CMD_ACKNOWLEDGE_SVC_PROBLEM 34 + +#define CMD_START_EXECUTING_SVC_CHECKS 35 +#define CMD_STOP_EXECUTING_SVC_CHECKS 36 + +#define CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS 37 +#define CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS 38 + +#define CMD_ENABLE_PASSIVE_SVC_CHECKS 39 +#define CMD_DISABLE_PASSIVE_SVC_CHECKS 40 + +#define CMD_ENABLE_EVENT_HANDLERS 41 +#define CMD_DISABLE_EVENT_HANDLERS 42 + +#define CMD_ENABLE_HOST_EVENT_HANDLER 43 +#define CMD_DISABLE_HOST_EVENT_HANDLER 44 + +#define CMD_ENABLE_SVC_EVENT_HANDLER 45 +#define CMD_DISABLE_SVC_EVENT_HANDLER 46 + +#define CMD_ENABLE_HOST_CHECK 47 +#define CMD_DISABLE_HOST_CHECK 48 + +#define CMD_START_OBSESSING_OVER_SVC_CHECKS 49 +#define CMD_STOP_OBSESSING_OVER_SVC_CHECKS 50 + +#define CMD_REMOVE_HOST_ACKNOWLEDGEMENT 51 +#define CMD_REMOVE_SVC_ACKNOWLEDGEMENT 52 + +#define CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS 53 +#define CMD_SCHEDULE_FORCED_SVC_CHECK 54 + +#define CMD_SCHEDULE_HOST_DOWNTIME 55 +#define CMD_SCHEDULE_SVC_DOWNTIME 56 + +#define CMD_ENABLE_HOST_FLAP_DETECTION 57 +#define CMD_DISABLE_HOST_FLAP_DETECTION 58 + +#define CMD_ENABLE_SVC_FLAP_DETECTION 59 +#define CMD_DISABLE_SVC_FLAP_DETECTION 60 + +#define CMD_ENABLE_FLAP_DETECTION 61 +#define CMD_DISABLE_FLAP_DETECTION 62 + +#define CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS 63 +#define CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS 64 + +#define CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS 65 +#define CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS 66 + +#define CMD_ENABLE_HOSTGROUP_SVC_CHECKS 67 +#define CMD_DISABLE_HOSTGROUP_SVC_CHECKS 68 + +#define CMD_CANCEL_HOST_DOWNTIME 69 /* not internally implemented */ +#define CMD_CANCEL_SVC_DOWNTIME 70 /* not internally implemented */ + +#define CMD_CANCEL_ACTIVE_HOST_DOWNTIME 71 /* old - no longer used */ +#define CMD_CANCEL_PENDING_HOST_DOWNTIME 72 /* old - no longer used */ + +#define CMD_CANCEL_ACTIVE_SVC_DOWNTIME 73 /* old - no longer used */ +#define CMD_CANCEL_PENDING_SVC_DOWNTIME 74 /* old - no longer used */ + +#define CMD_CANCEL_ACTIVE_HOST_SVC_DOWNTIME 75 /* unimplemented */ +#define CMD_CANCEL_PENDING_HOST_SVC_DOWNTIME 76 /* unimplemented */ + +#define CMD_FLUSH_PENDING_COMMANDS 77 + +#define CMD_DEL_HOST_DOWNTIME 78 +#define CMD_DEL_SVC_DOWNTIME 79 + +#define CMD_ENABLE_FAILURE_PREDICTION 80 +#define CMD_DISABLE_FAILURE_PREDICTION 81 + +#define CMD_ENABLE_PERFORMANCE_DATA 82 +#define CMD_DISABLE_PERFORMANCE_DATA 83 + +#define CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME 84 +#define CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME 85 +#define CMD_SCHEDULE_HOST_SVC_DOWNTIME 86 + +/* new commands in Nagios 2.x found below... */ +#define CMD_PROCESS_HOST_CHECK_RESULT 87 + +#define CMD_START_EXECUTING_HOST_CHECKS 88 +#define CMD_STOP_EXECUTING_HOST_CHECKS 89 + +#define CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS 90 +#define CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS 91 + +#define CMD_ENABLE_PASSIVE_HOST_CHECKS 92 +#define CMD_DISABLE_PASSIVE_HOST_CHECKS 93 + +#define CMD_START_OBSESSING_OVER_HOST_CHECKS 94 +#define CMD_STOP_OBSESSING_OVER_HOST_CHECKS 95 + +#define CMD_SCHEDULE_HOST_CHECK 96 +#define CMD_SCHEDULE_FORCED_HOST_CHECK 98 + +#define CMD_START_OBSESSING_OVER_SVC 99 +#define CMD_STOP_OBSESSING_OVER_SVC 100 + +#define CMD_START_OBSESSING_OVER_HOST 101 +#define CMD_STOP_OBSESSING_OVER_HOST 102 + +#define CMD_ENABLE_HOSTGROUP_HOST_CHECKS 103 +#define CMD_DISABLE_HOSTGROUP_HOST_CHECKS 104 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 105 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 106 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 107 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 108 + +#define CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS 109 +#define CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS 110 + +#define CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS 111 +#define CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS 112 + +#define CMD_ENABLE_SERVICEGROUP_SVC_CHECKS 113 +#define CMD_DISABLE_SERVICEGROUP_SVC_CHECKS 114 + +#define CMD_ENABLE_SERVICEGROUP_HOST_CHECKS 115 +#define CMD_DISABLE_SERVICEGROUP_HOST_CHECKS 116 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 117 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 118 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 119 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 120 + +#define CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME 121 +#define CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME 122 + +#define CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER 123 +#define CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER 124 + +#define CMD_CHANGE_HOST_EVENT_HANDLER 125 +#define CMD_CHANGE_SVC_EVENT_HANDLER 126 + +#define CMD_CHANGE_HOST_CHECK_COMMAND 127 +#define CMD_CHANGE_SVC_CHECK_COMMAND 128 + +#define CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL 129 +#define CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL 130 +#define CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL 131 + +#define CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS 132 +#define CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS 133 + +#define CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME 134 + +#define CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS 135 +#define CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS 136 + +#define CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME 137 + +#define CMD_ENABLE_SERVICE_FRESHNESS_CHECKS 138 +#define CMD_DISABLE_SERVICE_FRESHNESS_CHECKS 139 + +#define CMD_ENABLE_HOST_FRESHNESS_CHECKS 140 +#define CMD_DISABLE_HOST_FRESHNESS_CHECKS 141 + +#define CMD_SET_HOST_NOTIFICATION_NUMBER 142 +#define CMD_SET_SVC_NOTIFICATION_NUMBER 143 + +/* new commands in Nagios 3.x found below... */ +#define CMD_CHANGE_HOST_CHECK_TIMEPERIOD 144 +#define CMD_CHANGE_SVC_CHECK_TIMEPERIOD 145 + +#define CMD_PROCESS_FILE 146 + +#define CMD_CHANGE_CUSTOM_HOST_VAR 147 +#define CMD_CHANGE_CUSTOM_SVC_VAR 148 +#define CMD_CHANGE_CUSTOM_CONTACT_VAR 149 + +#define CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS 150 +#define CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS 151 +#define CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS 152 +#define CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS 153 + +#define CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS 154 +#define CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS 155 +#define CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS 156 +#define CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS 157 + +#define CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL 158 + +#define CMD_SEND_CUSTOM_HOST_NOTIFICATION 159 +#define CMD_SEND_CUSTOM_SVC_NOTIFICATION 160 + +#define CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD 161 +#define CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD 162 +#define CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD 163 +#define CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD 164 + +#define CMD_CHANGE_HOST_MODATTR 165 +#define CMD_CHANGE_SVC_MODATTR 166 +#define CMD_CHANGE_CONTACT_MODATTR 167 +#define CMD_CHANGE_CONTACT_MODHATTR 168 +#define CMD_CHANGE_CONTACT_MODSATTR 169 + +/* custom command introduced in Nagios 3.x */ +#define CMD_CUSTOM_COMMAND 999 + + + +/************************ SERVICE CHECK TYPES ****************************/ + +#define SERVICE_CHECK_ACTIVE 0 /* Nagios performed the service check */ +#define SERVICE_CHECK_PASSIVE 1 /* the service check result was submitted by an external source */ + + +/************************** HOST CHECK TYPES *****************************/ + +#define HOST_CHECK_ACTIVE 0 /* Nagios performed the host check */ +#define HOST_CHECK_PASSIVE 1 /* the host check result was submitted by an external source */ + + +/************************ SERVICE STATE TYPES ****************************/ + +#define SOFT_STATE 0 +#define HARD_STATE 1 + + +/************************* SCHEDULED DOWNTIME TYPES **********************/ + +#define SERVICE_DOWNTIME 1 /* service downtime */ +#define HOST_DOWNTIME 2 /* host downtime */ +#define ANY_DOWNTIME 3 /* host or service downtime */ + + +/************************** NOTIFICATION OPTIONS *************************/ + +#define NOTIFICATION_OPTION_NONE 0 +#define NOTIFICATION_OPTION_BROADCAST 1 +#define NOTIFICATION_OPTION_FORCED 2 +#define NOTIFICATION_OPTION_INCREMENT 4 + + +/************************** ACKNOWLEDGEMENT TYPES ************************/ + +#define HOST_ACKNOWLEDGEMENT 0 +#define SERVICE_ACKNOWLEDGEMENT 1 + +#define ACKNOWLEDGEMENT_NONE 0 +#define ACKNOWLEDGEMENT_NORMAL 1 +#define ACKNOWLEDGEMENT_STICKY 2 + + +/**************************** DEPENDENCY TYPES ***************************/ + +#define NOTIFICATION_DEPENDENCY 1 +#define EXECUTION_DEPENDENCY 2 + + + +/********************** HOST/SERVICE CHECK OPTIONS ***********************/ + +#define CHECK_OPTION_NONE 0 /* no check options */ +#define CHECK_OPTION_FORCE_EXECUTION 1 /* force execution of a check (ignores disabled services/hosts, invalid timeperiods) */ +#define CHECK_OPTION_FRESHNESS_CHECK 2 /* this is a freshness check */ +#define CHECK_OPTION_ORPHAN_CHECK 4 /* this is an orphan check */ + + +/**************************** PROGRAM MODES ******************************/ + +#define STANDBY_MODE 0 +#define ACTIVE_MODE 1 + + +/************************** LOG ROTATION MODES ***************************/ + +#define LOG_ROTATION_NONE 0 +#define LOG_ROTATION_HOURLY 1 +#define LOG_ROTATION_DAILY 2 +#define LOG_ROTATION_WEEKLY 3 +#define LOG_ROTATION_MONTHLY 4 + + +/***************************** LOG VERSIONS ******************************/ + +#define LOG_VERSION_1 "1.0" +#define LOG_VERSION_2 "2.0" + + + +/*************************** CHECK STATISTICS ****************************/ + +#define ACTIVE_SCHEDULED_SERVICE_CHECK_STATS 0 +#define ACTIVE_ONDEMAND_SERVICE_CHECK_STATS 1 +#define PASSIVE_SERVICE_CHECK_STATS 2 +#define ACTIVE_SCHEDULED_HOST_CHECK_STATS 3 +#define ACTIVE_ONDEMAND_HOST_CHECK_STATS 4 +#define PASSIVE_HOST_CHECK_STATS 5 +#define ACTIVE_CACHED_HOST_CHECK_STATS 6 +#define ACTIVE_CACHED_SERVICE_CHECK_STATS 7 +#define EXTERNAL_COMMAND_STATS 8 +#define PARALLEL_HOST_CHECK_STATS 9 +#define SERIAL_HOST_CHECK_STATS 10 +#define MAX_CHECK_STATS_TYPES 11 + + +/************************* GENERAL DEFINITIONS **************************/ + +#define OK 0 +#define ERROR -2 /* value was changed from -1 so as to not interfere with STATUS_UNKNOWN plugin result */ + + +#ifndef TRUE +#define TRUE 1 +#elif (TRUE!=1) +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#elif (FALSE!=0) +#define FALSE 0 +#endif + + +/****************** HOST CONFIG FILE READING OPTIONS ********************/ + +#define READ_HOSTS 1 +#define READ_HOSTGROUPS 2 +#define READ_CONTACTS 4 +#define READ_CONTACTGROUPS 8 +#define READ_SERVICES 16 +#define READ_COMMANDS 32 +#define READ_TIMEPERIODS 64 +#define READ_SERVICEESCALATIONS 128 +#define READ_HOSTGROUPESCALATIONS 256 /* no longer implemented */ +#define READ_SERVICEDEPENDENCIES 512 +#define READ_HOSTDEPENDENCIES 1024 +#define READ_HOSTESCALATIONS 2048 +#define READ_HOSTEXTINFO 4096 +#define READ_SERVICEEXTINFO 8192 +#define READ_SERVICEGROUPS 16384 + +#define READ_ALL_OBJECT_DATA READ_HOSTS | READ_HOSTGROUPS | READ_CONTACTS | READ_CONTACTGROUPS | READ_SERVICES | READ_COMMANDS | READ_TIMEPERIODS | READ_SERVICEESCALATIONS | READ_SERVICEDEPENDENCIES | READ_HOSTDEPENDENCIES | READ_HOSTESCALATIONS | READ_HOSTEXTINFO | READ_SERVICEEXTINFO | READ_SERVICEGROUPS + + +/************************** DATE RANGE TYPES ****************************/ + +#define DATERANGE_CALENDAR_DATE 0 /* 2008-12-25 */ +#define DATERANGE_MONTH_DATE 1 /* july 4 (specific month) */ +#define DATERANGE_MONTH_DAY 2 /* day 21 (generic month) */ +#define DATERANGE_MONTH_WEEK_DAY 3 /* 3rd thursday (specific month) */ +#define DATERANGE_WEEK_DAY 4 /* 3rd thursday (generic month) */ +#define DATERANGE_TYPES 5 + + +/************************** DATE/TIME TYPES *****************************/ + +#define LONG_DATE_TIME 0 +#define SHORT_DATE_TIME 1 +#define SHORT_DATE 2 +#define SHORT_TIME 3 +#define HTTP_DATE_TIME 4 /* time formatted for use in HTTP headers */ + + +/**************************** DATE FORMATS ******************************/ + +#define DATE_FORMAT_US 0 /* U.S. (MM-DD-YYYY HH:MM:SS) */ +#define DATE_FORMAT_EURO 1 /* European (DD-MM-YYYY HH:MM:SS) */ +#define DATE_FORMAT_ISO8601 2 /* ISO8601 (YYYY-MM-DD HH:MM:SS) */ +#define DATE_FORMAT_STRICT_ISO8601 3 /* ISO8601 (YYYY-MM-DDTHH:MM:SS) */ + + +/************************** MISC DEFINITIONS ****************************/ + +#define MAX_FILENAME_LENGTH 256 /* max length of path/filename that Nagios will process */ +#define MAX_INPUT_BUFFER 1024 /* size in bytes of max. input buffer (for reading files, misc stuff) */ +#define MAX_COMMAND_BUFFER 8192 /* max length of raw or processed command line */ +#define MAX_EXTERNAL_COMMAND_LENGTH 8192 /* max length of an external command */ + +#define MAX_DATETIME_LENGTH 48 + + +/************************* MODIFIED ATTRIBUTES **************************/ + +#define MODATTR_NONE 0 +#define MODATTR_NOTIFICATIONS_ENABLED 1 +#define MODATTR_ACTIVE_CHECKS_ENABLED 2 +#define MODATTR_PASSIVE_CHECKS_ENABLED 4 +#define MODATTR_EVENT_HANDLER_ENABLED 8 +#define MODATTR_FLAP_DETECTION_ENABLED 16 +#define MODATTR_FAILURE_PREDICTION_ENABLED 32 +#define MODATTR_PERFORMANCE_DATA_ENABLED 64 +#define MODATTR_OBSESSIVE_HANDLER_ENABLED 128 +#define MODATTR_EVENT_HANDLER_COMMAND 256 +#define MODATTR_CHECK_COMMAND 512 +#define MODATTR_NORMAL_CHECK_INTERVAL 1024 +#define MODATTR_RETRY_CHECK_INTERVAL 2048 +#define MODATTR_MAX_CHECK_ATTEMPTS 4096 +#define MODATTR_FRESHNESS_CHECKS_ENABLED 8192 +#define MODATTR_CHECK_TIMEPERIOD 16384 +#define MODATTR_CUSTOM_VARIABLE 32768 +#define MODATTR_NOTIFICATION_TIMEPERIOD 65536 + + diff --git a/nagios/config.h b/nagios/config.h new file mode 100644 index 0000000..3a9b588 --- /dev/null +++ b/nagios/config.h @@ -0,0 +1,336 @@ + +/* include/config.h. Generated by configure. */ +/************************************************************************ + * + * Nagios Config Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-02-2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + + +/***** NAGIOS STUFF *****/ + +#define DEFAULT_NAGIOS_USER "nagios" +#define DEFAULT_NAGIOS_GROUP "nagios" + +/* stop gcc from bitching about implicit asprintf declarations */ +#define _GNU_SOURCE 1 + +/* Event broker integration */ +#define USE_EVENT_BROKER 1 + +/* Embed a PERL interpreter into Nagios with optional cache for compiled code (contributed by Stephen Davies) */ +/* #undef EMBEDDEDPERL */ +/* #undef THREADEDPERL */ +/* 0 = cache, 1 = do not cache */ +#define DO_CLEAN "1" + +/* commands used by CGIs */ +#define TRACEROUTE_COMMAND "/usr/bin/traceroute" +/* #undef PING_COMMAND */ +/* #undef PING_PACKETS_FIRST */ + +/* Debugging options */ +/* function entry and exit */ +/* #undef DEBUG0 */ +/* general info messages */ +/* #undef DEBUG1 */ +/* warning messages */ +/* #undef DEBUG2 */ +/* service and host checks, other events */ +/* #undef DEBUG3 */ +/* service and host notifications */ +/* #undef DEBUG4 */ +/* SQL queries (defunct) */ +/* #undef DEBUG5 */ + +/* I/O implementations */ +#define USE_XSDDEFAULT 1 +#define USE_XCDDEFAULT 1 +#define USE_XRDDEFAULT 1 +#define USE_XODTEMPLATE 1 +#define USE_XPDDEFAULT 1 +#define USE_XDDDEFAULT 1 + + + +/***** FUNCTION DEFINITIONS *****/ + +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +/* #undef HAVE_SOCKET */ +#define HAVE_STRDUP 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOUL 1 +#define HAVE_INITGROUPS 1 +/* #undef HAVE_GETLOADAVG */ +#define HAVE_GDIMAGECREATETRUECOLOR 1 + + + +/***** ASPRINTF() AND FRIENDS *****/ + +/* #undef HAVE_VSNPRINTF */ +/* #undef HAVE_SNPRINTF */ +/* #undef HAVE_ASPRINTF */ +/* #undef HAVE_VASPRINTF */ +#define HAVE_C99_VSNPRINTF 1 +#define HAVE_VA_COPY 1 +/* #undef HAVE___VA_COPY */ + + + +/***** MISC DEFINITIONS *****/ + +#define USE_NANOSLEEP 1 +#define STDC_HEADERS 1 +#define HAVE_TM_ZONE 1 +/* #undef HAVE_TZNAME */ +/* #undef USE_PROC */ +#define SOCKET_SIZE_TYPE size_t +#define GETGROUPS_T gid_t +#define RETSIGTYPE void + + + +/***** HEADER FILES *****/ + +#include +#include + +/* needed for the time_t structures we use later... */ +/* this include must come before sys/resource.h or we can have problems on some OSes */ +#define TIME_WITH_SYS_TIME 1 +#define HAVE_SYS_TIME_H 1 +#if TIME_WITH_SYS_TIME +#include +#include +#else +#if HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + +#define HAVE_SYS_RESOURCE_H 1 +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +#define HAVE_LIMITS_H 1 +#ifdef HAVE_LIMITS_H +#include +#endif + +#define HAVE_PWD_H 1 +#ifdef HAVE_PWD_H +#include +#endif + +#define HAVE_GRP_H 1 +#ifdef HAVE_GRP_H +#include +#endif + +#define HAVE_STRINGS_H 1 +#ifdef HAVE_STRINGS_H +#include +#endif + +#define HAVE_STRING_H 1 +#ifdef HAVE_STRINGS_H +#include +#endif + +#define HAVE_UNISTD_H 1 +#ifdef HAVE_UNISTD_H +#include +#endif + +#define HAVE_SYSLOG_H 1 +#ifdef HAVE_SYSLOG_H +#include +#endif + +#define HAVE_SIGNAL_H 1 +#ifdef HAVE_SIGNAL_H +#include +#endif + +#define HAVE_SYS_STAT_H 1 +#ifdef HAVE_SYS_STAT_H +#include +#endif + +#define HAVE_SYS_MMAN_H 1 +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +#define HAVE_FCNTL_H 1 +#ifdef HAVE_FCNTL_H +#include +#endif + +#define HAVE_STDARG_H 1 +#ifdef HAVE_STDARG_H +#include +#endif + +#define HAVE_SYS_TYPES_H 1 +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#define HAVE_SYS_WAIT_H 1 +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#define HAVE_ERRNO_H 1 +#ifdef HAVE_ERRNO_H +#include +#endif + +#define HAVE_SYS_TIMEB_H 1 +#if HAVE_SYS_TIMEB_H +#include +#endif + +#define HAVE_SYS_IPC_H 1 +#ifdef HAVE_SYS_IPC_H +#include +#endif + +#define HAVE_SYS_MSG_H 1 +#ifdef HAVE_SYS_MSG_H +#include +#endif + +#define HAVE_MATH_H 1 +#ifdef HAVE_MATH_H +#include +#endif + +#define HAVE_CTYPE_H 1 +#ifdef HAVE_CTYPE_H +#include +#endif + +#define HAVE_DIRENT_H 1 +#ifdef HAVE_DIRENT_H +#include +#endif + +#define HAVE_PTHREAD_H 1 +#ifdef HAVE_PTHREAD_H +#include +#endif + +#define HAVE_REGEX_H 1 +#ifdef HAVE_REGEX_H +#include + +#define HAVE_SYS_SOCKET_H 1 +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +/* #undef HAVE_SOCKET */ +#ifdef HAVE_SOCKET_H +#include +#endif + +#define HAVE_NETINET_IN_H 1 +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#define HAVE_ARPA_INET_H 1 +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#define HAVE_NETDB_H 1 +#ifdef HAVE_NETDB_H +#include +#endif + +#define HAVE_LIBGEN_H 1 +#ifdef HAVE_LIBGEN_H +#include +#endif + +#define HAVE_SYS_UN_H 1 +#ifdef HAVE_SYS_UN_H +#include +#endif + +#define HAVE_SYS_POLL_H 1 +#ifdef HAVE_SYS_POLL_H +#include +#endif + +/* #define HAVE_GETOPT_H 1 */ +#ifdef HAVE_GETOPT_H +#include +#endif + +/* #undef HAVE_LINUX_MODULE_H */ +#ifdef HAVE_LINUX_MODULE_H +#include +#endif + +/* configure script should allow user to override ltdl choice, but this will do for now... */ +/* #undef USE_LTDL */ + +#ifdef HAVE_LTDL_H +#define USE_LTDL +#endif + +#ifdef USE_LTDL +#include +#else +/* #undef HAVE_DLFCN_H */ +#ifdef HAVE_DLFCN_H +#include +#endif +#endif + + +/* moved to end to prevent AIX compiler warnings */ +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif + + +/***** MARO DEFINITIONS *****/ + +/* this needs to come after all system include files, so we don't accidentally attempt to redefine it */ +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + + +#endif diff --git a/nagios/downtime.h b/nagios/downtime.h new file mode 100644 index 0000000..7fad115 --- /dev/null +++ b/nagios/downtime.h @@ -0,0 +1,101 @@ + +/***************************************************************************** + * + * DOWNTIME.H - Header file for scheduled downtime functions + * + * Copyright (c) 2001-2005 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-25-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _DOWNTIME_H +#define _DOWNTIME_H + +#include "config.h" +#include "common.h" +#include "objects.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* SCHEDULED_DOWNTIME_ENTRY structure */ +typedef struct scheduled_downtime_struct{ + int type; + char *host_name; + char *service_description; + time_t entry_time; + time_t start_time; + time_t end_time; + int fixed; + unsigned long triggered_by; + unsigned long duration; + unsigned long downtime_id; + char *author; + char *comment; +#ifdef NSCORE + unsigned long comment_id; + int is_in_effect; + int start_flex_downtime; + int incremented_pending_downtime; +#endif + struct scheduled_downtime_struct *next; + }scheduled_downtime; + + +#ifdef NSCORE +int initialize_downtime_data(char *); /* initializes scheduled downtime data */ +int cleanup_downtime_data(char *); /* cleans up scheduled downtime data */ + +int add_new_downtime(int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); +int add_new_host_downtime(char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); +int add_new_service_downtime(char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); + +int delete_host_downtime(unsigned long); +int delete_service_downtime(unsigned long); +int delete_downtime(int,unsigned long); + +int schedule_downtime(int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long *); +int unschedule_downtime(int,unsigned long); + +int register_downtime(int,unsigned long); +int handle_scheduled_downtime(scheduled_downtime *); +int handle_scheduled_downtime_by_id(unsigned long); + +int check_pending_flex_host_downtime(host *); +int check_pending_flex_service_downtime(service *); + +int check_for_expired_downtime(void); +#endif + +int add_host_downtime(char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long); +int add_service_downtime(char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long); +int add_downtime(int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long); + +scheduled_downtime *find_downtime(int,unsigned long); +scheduled_downtime *find_host_downtime(unsigned long); +scheduled_downtime *find_service_downtime(unsigned long); + +void free_downtime_data(void); /* frees memory allocated to scheduled downtime list */ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/locations.h b/nagios/locations.h new file mode 100644 index 0000000..bbd7ce5 --- /dev/null +++ b/nagios/locations.h @@ -0,0 +1,44 @@ + +/************************************************************************ + * + * Nagios Locations Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 04-30-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#define DEFAULT_TEMP_FILE "/usr/local/nagios/var/tempfile" +#define DEFAULT_TEMP_PATH "/tmp" +#define DEFAULT_CHECK_RESULT_PATH "/usr/local/nagios/var/spool/checkresults" +#define DEFAULT_STATUS_FILE "/usr/local/nagios/var/status.dat" +#define DEFAULT_LOG_FILE "/usr/local/nagios/var/nagios.log" +#define DEFAULT_LOG_ARCHIVE_PATH "/usr/local/nagios/var/archives/" +#define DEFAULT_DEBUG_FILE "/usr/local/nagios/var/nagios.debug" +#define DEFAULT_COMMENT_FILE "/usr/local/nagios/var/comments.dat" +#define DEFAULT_DOWNTIME_FILE "/usr/local/nagios/var/downtime.dat" +#define DEFAULT_RETENTION_FILE "/usr/local/nagios/var/retention.dat" +#define DEFAULT_COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd" +#define DEFAULT_CONFIG_FILE "/usr/local/nagios/etc/nagios.cfg" +#define DEFAULT_PHYSICAL_HTML_PATH "/usr/local/nagios/share" +#define DEFAULT_URL_HTML_PATH "/nagios" +#define DEFAULT_PHYSICAL_CGIBIN_PATH "/usr/local/nagios/sbin" +#define DEFAULT_URL_CGIBIN_PATH "/nagios/cgi-bin" +#define DEFAULT_CGI_CONFIG_FILE "/usr/local/nagios/etc/cgi.cfg" +#define DEFAULT_LOCK_FILE "/usr/local/nagios/var/nagios.lock" +#define DEFAULT_OBJECT_CACHE_FILE "/usr/local/nagios/var/objects.cache" +#define DEFAULT_PRECACHED_OBJECT_FILE "/usr/local/nagios/var/objects.precache" +#define DEFAULT_EVENT_BROKER_FILE "/usr/local/nagios/var/broker.socket" +#define DEFAULT_P1_FILE "/usr/local/nagios/bin/p1.pl" /**** EMBEDDED PERL ****/ +#define DEFAULT_AUTH_FILE "" /**** EMBEDDED PERL - IS THIS USED? ****/ diff --git a/nagios/macros.h b/nagios/macros.h new file mode 100644 index 0000000..95deff7 --- /dev/null +++ b/nagios/macros.h @@ -0,0 +1,264 @@ + +/************************************************************************ + * + * MACROS.H - Common macro functions + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-28-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _MACROS_H +#define _MACROS_H + +#include "config.h" +#include "common.h" +#include "objects.h" + + + +/****************** LENGTH LIMITATIONS ****************/ + +#define MAX_COMMAND_ARGUMENTS 32 /* maximum number of $ARGx$ macros */ + + +/****************** MACRO DEFINITIONS *****************/ + +#define MACRO_ENV_VAR_PREFIX "NAGIOS_" + +#define MAX_USER_MACROS 256 /* maximum number of $USERx$ macros */ + +#define MACRO_X_COUNT 153 /* size of macro_x[] array */ + +#define MACRO_HOSTNAME 0 +#define MACRO_HOSTALIAS 1 +#define MACRO_HOSTADDRESS 2 +#define MACRO_SERVICEDESC 3 +#define MACRO_SERVICESTATE 4 +#define MACRO_SERVICESTATEID 5 +#define MACRO_SERVICEATTEMPT 6 +#define MACRO_LONGDATETIME 7 +#define MACRO_SHORTDATETIME 8 +#define MACRO_DATE 9 +#define MACRO_TIME 10 +#define MACRO_TIMET 11 +#define MACRO_LASTHOSTCHECK 12 +#define MACRO_LASTSERVICECHECK 13 +#define MACRO_LASTHOSTSTATECHANGE 14 +#define MACRO_LASTSERVICESTATECHANGE 15 +#define MACRO_HOSTOUTPUT 16 +#define MACRO_SERVICEOUTPUT 17 +#define MACRO_HOSTPERFDATA 18 +#define MACRO_SERVICEPERFDATA 19 +#define MACRO_CONTACTNAME 20 +#define MACRO_CONTACTALIAS 21 +#define MACRO_CONTACTEMAIL 22 +#define MACRO_CONTACTPAGER 23 +#define MACRO_ADMINEMAIL 24 +#define MACRO_ADMINPAGER 25 +#define MACRO_HOSTSTATE 26 +#define MACRO_HOSTSTATEID 27 +#define MACRO_HOSTATTEMPT 28 +#define MACRO_NOTIFICATIONTYPE 29 +#define MACRO_NOTIFICATIONNUMBER 30 /* deprecated - see HOSTNOTIFICATIONNUMBER and SERVICENOTIFICATIONNUMBER macros */ +#define MACRO_HOSTEXECUTIONTIME 31 +#define MACRO_SERVICEEXECUTIONTIME 32 +#define MACRO_HOSTLATENCY 33 +#define MACRO_SERVICELATENCY 34 +#define MACRO_HOSTDURATION 35 +#define MACRO_SERVICEDURATION 36 +#define MACRO_HOSTDURATIONSEC 37 +#define MACRO_SERVICEDURATIONSEC 38 +#define MACRO_HOSTDOWNTIME 39 +#define MACRO_SERVICEDOWNTIME 40 +#define MACRO_HOSTSTATETYPE 41 +#define MACRO_SERVICESTATETYPE 42 +#define MACRO_HOSTPERCENTCHANGE 43 +#define MACRO_SERVICEPERCENTCHANGE 44 +#define MACRO_HOSTGROUPNAME 45 +#define MACRO_HOSTGROUPALIAS 46 +#define MACRO_SERVICEGROUPNAME 47 +#define MACRO_SERVICEGROUPALIAS 48 +#define MACRO_HOSTACKAUTHOR 49 +#define MACRO_HOSTACKCOMMENT 50 +#define MACRO_SERVICEACKAUTHOR 51 +#define MACRO_SERVICEACKCOMMENT 52 +#define MACRO_LASTSERVICEOK 53 +#define MACRO_LASTSERVICEWARNING 54 +#define MACRO_LASTSERVICEUNKNOWN 55 +#define MACRO_LASTSERVICECRITICAL 56 +#define MACRO_LASTHOSTUP 57 +#define MACRO_LASTHOSTDOWN 58 +#define MACRO_LASTHOSTUNREACHABLE 59 +#define MACRO_SERVICECHECKCOMMAND 60 +#define MACRO_HOSTCHECKCOMMAND 61 +#define MACRO_MAINCONFIGFILE 62 +#define MACRO_STATUSDATAFILE 63 +#define MACRO_HOSTDISPLAYNAME 64 +#define MACRO_SERVICEDISPLAYNAME 65 +#define MACRO_RETENTIONDATAFILE 66 +#define MACRO_OBJECTCACHEFILE 67 +#define MACRO_TEMPFILE 68 +#define MACRO_LOGFILE 69 +#define MACRO_RESOURCEFILE 70 +#define MACRO_COMMANDFILE 71 +#define MACRO_HOSTPERFDATAFILE 72 +#define MACRO_SERVICEPERFDATAFILE 73 +#define MACRO_HOSTACTIONURL 74 +#define MACRO_HOSTNOTESURL 75 +#define MACRO_HOSTNOTES 76 +#define MACRO_SERVICEACTIONURL 77 +#define MACRO_SERVICENOTESURL 78 +#define MACRO_SERVICENOTES 79 +#define MACRO_TOTALHOSTSUP 80 +#define MACRO_TOTALHOSTSDOWN 81 +#define MACRO_TOTALHOSTSUNREACHABLE 82 +#define MACRO_TOTALHOSTSDOWNUNHANDLED 83 +#define MACRO_TOTALHOSTSUNREACHABLEUNHANDLED 84 +#define MACRO_TOTALHOSTPROBLEMS 85 +#define MACRO_TOTALHOSTPROBLEMSUNHANDLED 86 +#define MACRO_TOTALSERVICESOK 87 +#define MACRO_TOTALSERVICESWARNING 88 +#define MACRO_TOTALSERVICESCRITICAL 89 +#define MACRO_TOTALSERVICESUNKNOWN 90 +#define MACRO_TOTALSERVICESWARNINGUNHANDLED 91 +#define MACRO_TOTALSERVICESCRITICALUNHANDLED 92 +#define MACRO_TOTALSERVICESUNKNOWNUNHANDLED 93 +#define MACRO_TOTALSERVICEPROBLEMS 94 +#define MACRO_TOTALSERVICEPROBLEMSUNHANDLED 95 +#define MACRO_PROCESSSTARTTIME 96 +#define MACRO_HOSTCHECKTYPE 97 +#define MACRO_SERVICECHECKTYPE 98 +#define MACRO_LONGHOSTOUTPUT 99 +#define MACRO_LONGSERVICEOUTPUT 100 +#define MACRO_TEMPPATH 101 +#define MACRO_HOSTNOTIFICATIONNUMBER 102 +#define MACRO_SERVICENOTIFICATIONNUMBER 103 +#define MACRO_HOSTNOTIFICATIONID 104 +#define MACRO_SERVICENOTIFICATIONID 105 +#define MACRO_HOSTEVENTID 106 +#define MACRO_LASTHOSTEVENTID 107 +#define MACRO_SERVICEEVENTID 108 +#define MACRO_LASTSERVICEEVENTID 109 +#define MACRO_HOSTGROUPNAMES 110 +#define MACRO_SERVICEGROUPNAMES 111 +#define MACRO_HOSTACKAUTHORNAME 112 +#define MACRO_HOSTACKAUTHORALIAS 113 +#define MACRO_SERVICEACKAUTHORNAME 114 +#define MACRO_SERVICEACKAUTHORALIAS 115 +#define MACRO_MAXHOSTATTEMPTS 116 +#define MACRO_MAXSERVICEATTEMPTS 117 +#define MACRO_SERVICEISVOLATILE 118 +#define MACRO_TOTALHOSTSERVICES 119 +#define MACRO_TOTALHOSTSERVICESOK 120 +#define MACRO_TOTALHOSTSERVICESWARNING 121 +#define MACRO_TOTALHOSTSERVICESUNKNOWN 122 +#define MACRO_TOTALHOSTSERVICESCRITICAL 123 +#define MACRO_HOSTGROUPNOTES 124 +#define MACRO_HOSTGROUPNOTESURL 125 +#define MACRO_HOSTGROUPACTIONURL 126 +#define MACRO_SERVICEGROUPNOTES 127 +#define MACRO_SERVICEGROUPNOTESURL 128 +#define MACRO_SERVICEGROUPACTIONURL 129 +#define MACRO_HOSTGROUPMEMBERS 130 +#define MACRO_SERVICEGROUPMEMBERS 131 +#define MACRO_CONTACTGROUPNAME 132 +#define MACRO_CONTACTGROUPALIAS 133 +#define MACRO_CONTACTGROUPMEMBERS 134 +#define MACRO_CONTACTGROUPNAMES 135 +#define MACRO_NOTIFICATIONRECIPIENTS 136 +#define MACRO_NOTIFICATIONISESCALATED 137 +#define MACRO_NOTIFICATIONAUTHOR 138 +#define MACRO_NOTIFICATIONAUTHORNAME 139 +#define MACRO_NOTIFICATIONAUTHORALIAS 140 +#define MACRO_NOTIFICATIONCOMMENT 141 +#define MACRO_EVENTSTARTTIME 142 +#define MACRO_HOSTPROBLEMID 143 +#define MACRO_LASTHOSTPROBLEMID 144 +#define MACRO_SERVICEPROBLEMID 145 +#define MACRO_LASTSERVICEPROBLEMID 146 +#define MACRO_ISVALIDTIME 147 +#define MACRO_NEXTVALIDTIME 148 +#define MACRO_LASTHOSTSTATE 149 +#define MACRO_LASTHOSTSTATEID 150 +#define MACRO_LASTSERVICESTATE 151 +#define MACRO_LASTSERVICESTATEID 152 + + + +/************* MACRO CLEANING OPTIONS *****************/ + +#define STRIP_ILLEGAL_MACRO_CHARS 1 +#define ESCAPE_MACRO_CHARS 2 +#define URL_ENCODE_MACRO_CHARS 4 + + + +/****************** MACRO FUNCTIONS ******************/ + +int process_macros(char *,char **,int); /* replace macros with their actual values */ +char *clean_macro_chars(char *,int); /* cleans macros characters before insertion into output string */ + +int grab_service_macros(service *); /* updates the service macro data */ +int grab_host_macros(host *); /* updates the host macro data */ +int grab_servicegroup_macros(servicegroup *); /* updates servicegroup macros */ +int grab_hostgroup_macros(hostgroup *); /* updates hostgroup macros */ +int grab_contact_macros(contact *); /* updates the contact macro data */ +int grab_contactgroup_macros(contactgroup *); /* updates contactgroup macros */ +int grab_datetime_macros(void); /* updates date/time macros */ +int grab_on_demand_macro(char *); /* fetches an on-demand macro */ + +char *get_url_encoded_string(char *); /* URL encode a string */ + +int init_macros(void); +int init_macrox_names(void); +int add_macrox_name(int,char *); +int free_macrox_names(void); + +int clear_argv_macros(void); +int clear_volatile_macros(void); +int clear_host_macros(void); +int clear_service_macros(void); +int clear_hostgroup_macros(void); +int clear_servicegroup_macros(void); +int clear_contact_macros(void); +int clear_contactgroup_macros(void); +int clear_summary_macros(void); + +int grab_macro_value(char *,char **,int *,int *); +int grab_macrox_value(int,char *,char *,char **,int *); +int grab_custom_macro_value(char *,char *,char *,char **); +int grab_datetime_macro(int,char *,char *,char **); +int grab_standard_host_macro(int,host *,char **,int *); +int grab_standard_hostgroup_macro(int,hostgroup *,char **); +int grab_standard_service_macro(int,service *,char **,int *); +int grab_standard_servicegroup_macro(int,servicegroup *,char **); +int grab_standard_contact_macro(int,contact *,char **); +int grab_contact_address_macro(int,contact *,char **); +int grab_standard_contactgroup_macro(int,contactgroup *,char **); +int grab_custom_object_macro(char *,customvariablesmember *,char **); + + +#ifdef NSCORE +int set_all_macro_environment_vars(int); +int set_macrox_environment_vars(int); +int set_argv_macro_environment_vars(int); +int set_custom_macro_environment_vars(int); +int set_contact_address_environment_vars(int); +int set_macro_environment_var(char *,char *,int); +#endif + +#endif diff --git a/nagios/nagios.h b/nagios/nagios.h new file mode 100644 index 0000000..798f3e9 --- /dev/null +++ b/nagios/nagios.h @@ -0,0 +1,822 @@ + +/************************************************************************ + * + * Nagios Main Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-14-2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _NAGIOS_H +#define _NAGIOS_H + +#ifndef __GNUC__ +# define __attribute__(x) /* nothing */ +#endif + +#include "config.h" +#include "common.h" +#include "locations.h" +#include "objects.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/************* MISC LENGTH/SIZE DEFINITIONS ***********/ + +/* + NOTE: Plugin length is artificially capped at 8k to prevent runaway plugins from returning MBs/GBs of data + back to Nagios. If you increase the 8k cap by modifying this value, make sure you also increase the value + of MAX_EXTERNAL_COMMAND_LENGTH in common.h to allow for passive checks results received through the external + command file. EG 10/19/07 +*/ +#define MAX_PLUGIN_OUTPUT_LENGTH 8192 /* max length of plugin output (including perf data) */ + + + +/******************* DEFAULT VALUES *******************/ + +#define DEFAULT_LOG_LEVEL 1 /* log all events to main log file */ +#define DEFAULT_USE_SYSLOG 1 /* log events to syslog? 1=yes, 0=no */ +#define DEFAULT_SYSLOG_LEVEL 2 /* log only severe events to syslog */ + +#define DEFAULT_NOTIFICATION_LOGGING 1 /* log notification events? 1=yes, 0=no */ + +#define DEFAULT_INTER_CHECK_DELAY 5.0 /* seconds between initial service check scheduling */ +#define DEFAULT_INTERLEAVE_FACTOR 1 /* default interleave to use when scheduling checks */ +#define DEFAULT_SLEEP_TIME 0.5 /* seconds between event run checks */ +#define DEFAULT_INTERVAL_LENGTH 60 /* seconds per interval unit for check scheduling */ +#define DEFAULT_RETRY_INTERVAL 30 /* services are retried in 30 seconds if they're not OK */ +#define DEFAULT_COMMAND_CHECK_INTERVAL -1 /* interval to check for external commands (default = as often as possible) */ +#define DEFAULT_CHECK_REAPER_INTERVAL 10 /* interval in seconds to reap host and service check results */ +#define DEFAULT_MAX_REAPER_TIME 30 /* maximum number of seconds to spend reaping service checks before we break out for a while */ +#define DEFAULT_MAX_CHECK_RESULT_AGE 3600 /* maximum number of seconds that a check result file is considered to be valid */ +#define DEFAULT_MAX_PARALLEL_SERVICE_CHECKS 0 /* maximum number of service checks we can have running at any given time (0=unlimited) */ +#define DEFAULT_RETENTION_UPDATE_INTERVAL 60 /* minutes between auto-save of retention data */ +#define DEFAULT_RETENTION_SCHEDULING_HORIZON 900 /* max seconds between program restarts that we will preserve scheduling information */ +#define DEFAULT_STATUS_UPDATE_INTERVAL 60 /* seconds between aggregated status data updates */ +#define DEFAULT_FRESHNESS_CHECK_INTERVAL 60 /* seconds between service result freshness checks */ +#define DEFAULT_AUTO_RESCHEDULING_INTERVAL 30 /* seconds between host and service check rescheduling events */ +#define DEFAULT_AUTO_RESCHEDULING_WINDOW 180 /* window of time (in seconds) for which we should reschedule host and service checks */ +#define DEFAULT_ORPHAN_CHECK_INTERVAL 60 /* seconds between checks for orphaned hosts and services */ + +#define DEFAULT_NOTIFICATION_TIMEOUT 30 /* max time in seconds to wait for notification commands to complete */ +#define DEFAULT_EVENT_HANDLER_TIMEOUT 30 /* max time in seconds to wait for event handler commands to complete */ +#define DEFAULT_HOST_CHECK_TIMEOUT 30 /* max time in seconds to wait for host check commands to complete */ +#define DEFAULT_SERVICE_CHECK_TIMEOUT 60 /* max time in seconds to wait for service check commands to complete */ +#define DEFAULT_OCSP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_OCHP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_PERFDATA_TIMEOUT 5 /* max time in seconds to wait for performance data commands to complete */ +#define DEFAULT_TIME_CHANGE_THRESHOLD 900 /* compensate for time changes of more than 15 minutes */ + +#define DEFAULT_LOG_HOST_RETRIES 0 /* don't log host retries */ +#define DEFAULT_LOG_SERVICE_RETRIES 0 /* don't log service retries */ +#define DEFAULT_LOG_EVENT_HANDLERS 1 /* log event handlers */ +#define DEFAULT_LOG_INITIAL_STATES 0 /* don't log initial service and host states */ +#define DEFAULT_LOG_EXTERNAL_COMMANDS 1 /* log external commands */ +#define DEFAULT_LOG_PASSIVE_CHECKS 1 /* log passive service checks */ + +#define DEFAULT_DEBUG_LEVEL 0 /* don't log any debugging information */ +#define DEFAULT_DEBUG_VERBOSITY 1 +#define DEFAULT_MAX_DEBUG_FILE_SIZE 1000000 /* max size of debug log */ + +#define DEFAULT_AGGRESSIVE_HOST_CHECKING 0 /* don't use "aggressive" host checking */ +#define DEFAULT_CHECK_EXTERNAL_COMMANDS 1 /* check for external commands */ +#define DEFAULT_CHECK_ORPHANED_SERVICES 1 /* check for orphaned services */ +#define DEFAULT_CHECK_ORPHANED_HOSTS 1 /* check for orphaned hosts */ +#define DEFAULT_ENABLE_FLAP_DETECTION 0 /* don't enable flap detection */ +#define DEFAULT_PROCESS_PERFORMANCE_DATA 0 /* don't process performance data */ +#define DEFAULT_CHECK_SERVICE_FRESHNESS 1 /* check service result freshness */ +#define DEFAULT_CHECK_HOST_FRESHNESS 0 /* don't check host result freshness */ +#define DEFAULT_AUTO_RESCHEDULE_CHECKS 0 /* don't auto-reschedule host and service checks */ +#define DEFAULT_TRANSLATE_PASSIVE_HOST_CHECKS 0 /* should we translate DOWN/UNREACHABLE passive host checks? */ +#define DEFAULT_PASSIVE_HOST_CHECKS_SOFT 0 /* passive host checks are treated as HARD by default */ + +#define DEFAULT_LOW_SERVICE_FLAP_THRESHOLD 20.0 /* low threshold for detection of service flapping */ +#define DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD 30.0 /* high threshold for detection of service flapping */ +#define DEFAULT_LOW_HOST_FLAP_THRESHOLD 20.0 /* low threshold for detection of host flapping */ +#define DEFAULT_HIGH_HOST_FLAP_THRESHOLD 30.0 /* high threshold for detection of host flapping */ + +#define DEFAULT_HOST_CHECK_SPREAD 30 /* max minutes to schedule all initial host checks */ +#define DEFAULT_SERVICE_CHECK_SPREAD 30 /* max minutes to schedule all initial service checks */ + +#define DEFAULT_CACHED_HOST_CHECK_HORIZON 15 /* max age in seconds that cached host checks can be used */ +#define DEFAULT_CACHED_SERVICE_CHECK_HORIZON 15 /* max age in seconds that cached service checks can be used */ +#define DEFAULT_ENABLE_PREDICTIVE_HOST_DEPENDENCY_CHECKS 1 /* should we use predictive host dependency checks? */ +#define DEFAULT_ENABLE_PREDICTIVE_SERVICE_DEPENDENCY_CHECKS 1 /* should we use predictive service dependency checks? */ + +#define DEFAULT_USE_LARGE_INSTALLATION_TWEAKS 0 /* don't use tweaks for large Nagios installations */ + +#define DEFAULT_ENABLE_EMBEDDED_PERL 0 /* enable embedded Perl interpreter (if compiled in) */ +#define DEFAULT_USE_EMBEDDED_PERL_IMPLICITLY 1 /* by default, embedded Perl is used for Perl plugins that don't explicitly disable it */ + +#define DEFAULT_ADDITIONAL_FRESHNESS_LATENCY 15 /* seconds to be added to freshness thresholds when automatically calculated by Nagios */ + +#define DEFAULT_CHECK_FOR_UPDATES 1 /* should we check for new Nagios releases? */ +#define DEFAULT_BARE_UPDATE_CHECK 0 /* report current version and new installs */ +#define MINIMUM_UPDATE_CHECK_INTERVAL 60*60*22 /* 22 hours minimum between checks - please be kind to our servers! */ +#define BASE_UPDATE_CHECK_INTERVAL 60*60*22 /* 22 hours base interval */ +#define UPDATE_CHECK_INTERVAL_WOBBLE 60*60*4 /* 4 hour wobble on top of base interval */ +#define BASE_UPDATE_CHECK_RETRY_INTERVAL 60*60*1 /* 1 hour base retry interval */ +#define UPDATE_CHECK_RETRY_INTERVAL_WOBBLE 60*60*3 /* 3 hour wobble on top of base retry interval */ + + +/******************* LOGGING TYPES ********************/ + +#define NSLOG_RUNTIME_ERROR 1 +#define NSLOG_RUNTIME_WARNING 2 + +#define NSLOG_VERIFICATION_ERROR 4 +#define NSLOG_VERIFICATION_WARNING 8 + +#define NSLOG_CONFIG_ERROR 16 +#define NSLOG_CONFIG_WARNING 32 + +#define NSLOG_PROCESS_INFO 64 +#define NSLOG_EVENT_HANDLER 128 +/*#define NSLOG_NOTIFICATION 256*/ /* NOT USED ANYMORE - CAN BE REUSED */ +#define NSLOG_EXTERNAL_COMMAND 512 + +#define NSLOG_HOST_UP 1024 +#define NSLOG_HOST_DOWN 2048 +#define NSLOG_HOST_UNREACHABLE 4096 + +#define NSLOG_SERVICE_OK 8192 +#define NSLOG_SERVICE_UNKNOWN 16384 +#define NSLOG_SERVICE_WARNING 32768 +#define NSLOG_SERVICE_CRITICAL 65536 + +#define NSLOG_PASSIVE_CHECK 131072 + +#define NSLOG_INFO_MESSAGE 262144 + +#define NSLOG_HOST_NOTIFICATION 524288 +#define NSLOG_SERVICE_NOTIFICATION 1048576 + + +/***************** DEBUGGING LEVELS *******************/ + +#define DEBUGL_ALL -1 +#define DEBUGL_NONE 0 +#define DEBUGL_FUNCTIONS 1 +#define DEBUGL_CONFIG 2 +#define DEBUGL_PROCESS 4 +#define DEBUGL_STATUSDATA 4 +#define DEBUGL_RETENTIONDATA 4 +#define DEBUGL_EVENTS 8 +#define DEBUGL_CHECKS 16 +#define DEBUGL_IPC 16 +#define DEBUGL_FLAPPING 16 +#define DEBUGL_EVENTHANDLERS 16 +#define DEBUGL_PERFDATA 16 +#define DEBUGL_NOTIFICATIONS 32 +#define DEBUGL_EVENTBROKER 64 +#define DEBUGL_EXTERNALCOMMANDS 128 +#define DEBUGL_COMMANDS 256 +#define DEBUGL_DOWNTIME 512 +#define DEBUGL_COMMENTS 1024 +#define DEBUGL_MACROS 2048 + +#define DEBUGV_BASIC 0 +#define DEBUGV_MORE 1 +#define DEBUGV_MOST 2 + + +/******************** HOST STATUS *********************/ + +#define HOST_UP 0 +#define HOST_DOWN 1 +#define HOST_UNREACHABLE 2 + + + +/******************* STATE LOGGING TYPES **************/ + +#define INITIAL_STATES 1 +#define CURRENT_STATES 2 + + + +/************ SERVICE DEPENDENCY VALUES ***************/ + +#define DEPENDENCIES_OK 0 +#define DEPENDENCIES_FAILED 1 + + + +/*********** ROUTE CHECK PROPAGATION TYPES ************/ + +#define PROPAGATE_TO_PARENT_HOSTS 1 +#define PROPAGATE_TO_CHILD_HOSTS 2 + + + +/****************** SERVICE STATES ********************/ + +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN 3 /* changed from -1 on 02/24/2001 */ + + + +/****************** FLAPPING TYPES ********************/ + +#define HOST_FLAPPING 0 +#define SERVICE_FLAPPING 1 + + + +/**************** NOTIFICATION TYPES ******************/ + +#define HOST_NOTIFICATION 0 +#define SERVICE_NOTIFICATION 1 + + + +/************* NOTIFICATION REASON TYPES ***************/ + +#define NOTIFICATION_NORMAL 0 +#define NOTIFICATION_ACKNOWLEDGEMENT 1 +#define NOTIFICATION_FLAPPINGSTART 2 +#define NOTIFICATION_FLAPPINGSTOP 3 +#define NOTIFICATION_FLAPPINGDISABLED 4 +#define NOTIFICATION_DOWNTIMESTART 5 +#define NOTIFICATION_DOWNTIMEEND 6 +#define NOTIFICATION_DOWNTIMECANCELLED 7 +#define NOTIFICATION_CUSTOM 99 + + + +/**************** EVENT HANDLER TYPES *****************/ + +#define HOST_EVENTHANDLER 0 +#define SERVICE_EVENTHANDLER 1 +#define GLOBAL_HOST_EVENTHANDLER 2 +#define GLOBAL_SERVICE_EVENTHANDLER 3 + + + +/***************** STATE CHANGE TYPES *****************/ + +#define HOST_STATECHANGE 0 +#define SERVICE_STATECHANGE 1 + + + +/***************** OBJECT CHECK TYPES *****************/ +#define SERVICE_CHECK 0 +#define HOST_CHECK 1 + + + +/******************* EVENT TYPES **********************/ + +#define EVENT_SERVICE_CHECK 0 /* active service check */ +#define EVENT_COMMAND_CHECK 1 /* external command check */ +#define EVENT_LOG_ROTATION 2 /* log file rotation */ +#define EVENT_PROGRAM_SHUTDOWN 3 /* program shutdown */ +#define EVENT_PROGRAM_RESTART 4 /* program restart */ +#define EVENT_CHECK_REAPER 5 /* reaps results from host and service checks */ +#define EVENT_ORPHAN_CHECK 6 /* checks for orphaned hosts and services */ +#define EVENT_RETENTION_SAVE 7 /* save (dump) retention data */ +#define EVENT_STATUS_SAVE 8 /* save (dump) status data */ +#define EVENT_SCHEDULED_DOWNTIME 9 /* scheduled host or service downtime */ +#define EVENT_SFRESHNESS_CHECK 10 /* checks service result "freshness" */ +#define EVENT_EXPIRE_DOWNTIME 11 /* checks for (and removes) expired scheduled downtime */ +#define EVENT_HOST_CHECK 12 /* active host check */ +#define EVENT_HFRESHNESS_CHECK 13 /* checks host result "freshness" */ +#define EVENT_RESCHEDULE_CHECKS 14 /* adjust scheduling of host and service checks */ +#define EVENT_EXPIRE_COMMENT 15 /* removes expired comments */ +#define EVENT_CHECK_PROGRAM_UPDATE 16 /* checks for new version of Nagios */ +#define EVENT_SLEEP 98 /* asynchronous sleep event that occurs when event queues are empty */ +#define EVENT_USER_FUNCTION 99 /* USER-defined function (modules) */ + + + +/******* INTER-CHECK DELAY CALCULATION TYPES **********/ + +#define ICD_NONE 0 /* no inter-check delay */ +#define ICD_DUMB 1 /* dumb delay of 1 second */ +#define ICD_SMART 2 /* smart delay */ +#define ICD_USER 3 /* user-specified delay */ + + + +/******* INTERLEAVE FACTOR CALCULATION TYPES **********/ + +#define ILF_USER 0 /* user-specified interleave factor */ +#define ILF_SMART 1 /* smart interleave */ + + + +/************ SCHEDULED DOWNTIME TYPES ****************/ + +#define ACTIVE_DOWNTIME 0 /* active downtime - currently in effect */ +#define PENDING_DOWNTIME 1 /* pending downtime - scheduled for the future */ + + + +/****************** DATA STRUCTURES *******************/ + +/* TIMED_EVENT structure */ +typedef struct timed_event_struct{ + int event_type; + time_t run_time; + int recurring; + unsigned long event_interval; + int compensate_for_time_change; + void *timing_func; + void *event_data; + void *event_args; + int event_options; + struct timed_event_struct *next; + struct timed_event_struct *prev; + }timed_event; + + +/* NOTIFY_LIST structure */ +typedef struct notify_list_struct{ + contact *this_should_be_named_other_than_contact; + struct notify_list_struct *next; + }notification; + + +/* CHECK_RESULT structure */ +typedef struct check_result_struct{ + int object_check_type; /* is this a service or a host check? */ + char *host_name; /* host name */ + char *service_description; /* service description */ + int check_type; /* was this an active or passive service check? */ + int check_options; + int scheduled_check; /* was this a scheduled or an on-demand check? */ + int reschedule_check; /* should we reschedule the next check */ + char *output_file; /* what file is the output stored in? */ + FILE *output_file_fp; + int output_file_fd; + double latency; + struct timeval start_time; /* time the service check was initiated */ + struct timeval finish_time; /* time the service check was completed */ + int early_timeout; /* did the service check timeout? */ + int exited_ok; /* did the plugin check return okay? */ + int return_code; /* plugin return code */ + char *output; /* plugin output */ + struct check_result_struct *next; + }check_result; + + +/* SCHED_INFO structure */ +typedef struct sched_info_struct{ + int total_services; + int total_scheduled_services; + int total_hosts; + int total_scheduled_hosts; + double average_services_per_host; + double average_scheduled_services_per_host; + unsigned long service_check_interval_total; + unsigned long host_check_interval_total; + double average_service_execution_time; + double average_service_check_interval; + double average_host_check_interval; + double average_service_inter_check_delay; + double average_host_inter_check_delay; + double service_inter_check_delay; + double host_inter_check_delay; + int service_interleave_factor; + int max_service_check_spread; + int max_host_check_spread; + time_t first_service_check; + time_t last_service_check; + time_t first_host_check; + time_t last_host_check; + }sched_info; + + +/* PASSIVE_CHECK_RESULT structure */ +typedef struct passive_check_result_struct{ + int object_check_type; + char *host_name; + char *service_description; + int return_code; + char *output; + time_t check_time; + double latency; + struct passive_check_result_struct *next; + }passive_check_result; + + +/* CIRCULAR_BUFFER structure - used by worker threads */ +typedef struct circular_buffer_struct{ + void **buffer; + int tail; + int head; + int items; + int high; /* highest number of items that has ever been stored in buffer */ + unsigned long overflow; + pthread_mutex_t buffer_lock; + }circular_buffer; + + +/* MMAPFILE structure - used for reading files via mmap() */ +typedef struct mmapfile_struct{ + char *path; + int mode; + int fd; + unsigned long file_size; + unsigned long current_position; + unsigned long current_line; + void *mmap_buf; + }mmapfile; + + +/* DBUF structure - dynamic string storage */ +typedef struct dbuf_struct{ + char *buf; + unsigned long used_size; + unsigned long allocated_size; + unsigned long chunk_size; + }dbuf; + + +#define CHECK_STATS_BUCKETS 15 + +/* used for tracking host and service check statistics */ +typedef struct check_stats_struct{ + int current_bucket; + int bucket[CHECK_STATS_BUCKETS]; + int overflow_bucket; + int minute_stats[3]; + time_t last_update; + }check_stats; + + +/******************* THREAD STUFF ********************/ + +/* slots in circular buffers */ +#define DEFAULT_EXTERNAL_COMMAND_BUFFER_SLOTS 4096 + +/* worker threads */ +#define TOTAL_WORKER_THREADS 1 + +#define COMMAND_WORKER_THREAD 0 + + + +/******************** FUNCTIONS **********************/ + +/**** Configuration Functions ****/ +int read_main_config_file(char *); /* reads the main config file (nagios.cfg) */ +int read_resource_file(char *); /* processes macros in resource file */ +int read_all_object_data(char *); /* reads all object config data */ + + +/**** Setup Functions ****/ +int pre_flight_check(void); /* try and verify the configuration data */ +int pre_flight_object_check(int *,int *); /* verify object relationships and settings */ +int pre_flight_circular_check(int *,int *); /* detects circular dependencies and paths */ +void init_timing_loop(void); /* setup the initial scheduling queue */ +void setup_sighandler(void); /* trap signals */ +void reset_sighandler(void); /* reset signals to default action */ +int daemon_init(void); /* switches to daemon mode */ +int drop_privileges(char *,char *); /* drops privileges before startup */ +void display_scheduling_info(void); /* displays service check scheduling information */ + + +/**** Event Queue Functions ****/ +int schedule_new_event(int,int,time_t,int,unsigned long,void *,int,void *,void *,int); /* schedules a new timed event */ +void reschedule_event(timed_event *,timed_event **,timed_event **); /* reschedules an event */ +void add_event(timed_event *,timed_event **,timed_event **); /* adds an event to the execution queue */ +void remove_event(timed_event *,timed_event **,timed_event **); /* remove an event from the execution queue */ +int event_execution_loop(void); /* main monitoring/event handler loop */ +int handle_timed_event(timed_event *); /* top level handler for timed events */ +void adjust_check_scheduling(void); /* auto-adjusts scheduling of host and service checks */ +void compensate_for_system_time_change(unsigned long,unsigned long); /* attempts to compensate for a change in the system time */ +void adjust_timestamp_for_time_change(time_t,time_t,unsigned long,time_t *); /* adjusts a timestamp variable for a system time change */ +void resort_event_list(timed_event **,timed_event **); /* resorts event list by event run time for system time changes */ + + +/**** IPC Functions ****/ +int move_check_result_to_queue(char *); +int process_check_result_queue(char *); +int process_check_result_file(char *); +int add_check_result_to_list(check_result *); +check_result *read_check_result(void); /* reads a host/service check result from the list in memory */ +int delete_check_result_file(char *); +int free_check_result_list(void); +int init_check_result(check_result *); +int free_check_result(check_result *); /* frees memory associated with a host/service check result */ +int parse_check_output(char *,char **,char **,char **,int,int); +int open_command_file(void); /* creates the external command file as a named pipe (FIFO) and opens it for reading */ +int close_command_file(void); /* closes and deletes the external command file (FIFO) */ + + +/**** Monitoring/Event Handler Functions ****/ +int check_service_dependencies(service *,int); /* checks service dependencies */ +int check_host_dependencies(host *,int); /* checks host dependencies */ +void check_for_orphaned_services(void); /* checks for orphaned services */ +void check_for_orphaned_hosts(void); /* checks for orphaned hosts */ +void check_service_result_freshness(void); /* checks the "freshness" of service check results */ +int is_service_result_fresh(service *,time_t,int); /* determines if a service's check results are fresh */ +void check_host_result_freshness(void); /* checks the "freshness" of host check results */ +int is_host_result_fresh(host *,time_t,int); /* determines if a host's check results are fresh */ +int my_system(char *,int,int *,double *,char **,int); /* executes a command via popen(), but also protects against timeouts */ + + +/**** Flap Detection Functions ****/ +void check_for_service_flapping(service *,int,int); /* determines whether or not a service is "flapping" between states */ +void check_for_host_flapping(host *,int,int,int); /* determines whether or not a host is "flapping" between states */ +void set_service_flap(service *,double,double,double,int); /* handles a service that is flapping */ +void clear_service_flap(service *,double,double,double); /* handles a service that has stopped flapping */ +void set_host_flap(host *,double,double,double,int); /* handles a host that is flapping */ +void clear_host_flap(host *,double,double,double); /* handles a host that has stopped flapping */ +void enable_flap_detection_routines(void); /* enables flap detection on a program-wide basis */ +void disable_flap_detection_routines(void); /* disables flap detection on a program-wide basis */ +void enable_host_flap_detection(host *); /* enables flap detection for a particular host */ +void disable_host_flap_detection(host *); /* disables flap detection for a particular host */ +void enable_service_flap_detection(service *); /* enables flap detection for a particular service */ +void disable_service_flap_detection(service *); /* disables flap detection for a particular service */ +void handle_host_flap_detection_disabled(host *); /* handles the details when flap detection is disabled globally or on a per-host basis */ +void handle_service_flap_detection_disabled(service *); /* handles the details when flap detection is disabled globally or on a per-service basis */ + + +/**** Route/Host Check Functions ****/ +int perform_on_demand_host_check(host *,int *,int,int,unsigned long); +int perform_scheduled_host_check(host *,int,double); +int check_host_check_viability_3x(host *,int,int *,time_t *); +int adjust_host_check_attempt_3x(host *,int); +int determine_host_reachability(host *); +int process_host_check_result_3x(host *,int,char *,int,int,int,unsigned long); +int perform_on_demand_host_check_3x(host *,int *,int,int,unsigned long); +int run_sync_host_check_3x(host *,int *,int,int,unsigned long); +int execute_sync_host_check_3x(host *); +int run_scheduled_host_check_3x(host *,int,double); +int run_async_host_check_3x(host *,int,double,int,int,int *,time_t *); +int handle_async_host_check_result_3x(host *,check_result *); + + +/**** Service Check Functions ****/ +int check_service_check_viability(service *,int,int *,time_t *); +int run_scheduled_service_check(service *,int,double); +int run_async_service_check(service *,int,double,int,int,int *,time_t *); +int handle_async_service_check_result(service *,check_result *); + + +/**** Event Handler Functions ****/ +int handle_host_state(host *); /* top level host state handler */ + + + +/**** Common Check Fucntions *****/ +int reap_check_results(void); + + +/**** Check Statistics Functions ****/ +int init_check_stats(void); +int update_check_stats(int,time_t); +int generate_check_stats(void); + + + +/**** Event Handler Functions ****/ +int obsessive_compulsive_service_check_processor(service *); /* distributed monitoring craziness... */ +int obsessive_compulsive_host_check_processor(host *); /* distributed monitoring craziness... */ +int handle_service_event(service *); /* top level service event logic */ +int run_service_event_handler(service *); /* runs the event handler for a specific service */ +int run_global_service_event_handler(service *); /* runs the global service event handler */ +int handle_host_event(host *); /* top level host event logic */ +int run_host_event_handler(host *); /* runs the event handler for a specific host */ +int run_global_host_event_handler(host *); /* runs the global host event handler */ + + +/**** Notification Functions ****/ +int check_service_notification_viability(service *,int,int); /* checks viability of notifying all contacts about a service */ +int is_valid_escalation_for_service_notification(service *,serviceescalation *,int); /* checks if an escalation entry is valid for a particular service notification */ +int should_service_notification_be_escalated(service *); /* checks if a service notification should be escalated */ +int service_notification(service *,int,char *,char *,int); /* notify all contacts about a service (problem or recovery) */ +int check_contact_service_notification_viability(contact *,service *,int,int); /* checks viability of notifying a contact about a service */ +int notify_contact_of_service(contact *,service *,int,char *,char *,int,int); /* notify a single contact about a service */ +int check_host_notification_viability(host *,int,int); /* checks viability of notifying all contacts about a host */ +int is_valid_escalation_for_host_notification(host *,hostescalation *,int); /* checks if an escalation entry is valid for a particular host notification */ +int should_host_notification_be_escalated(host *); /* checks if a host notification should be escalated */ +int host_notification(host *,int,char *,char *,int); /* notify all contacts about a host (problem or recovery) */ +int check_contact_host_notification_viability(contact *,host *,int,int); /* checks viability of notifying a contact about a host */ +int notify_contact_of_host(contact *,host *,int,char *,char *,int,int); /* notify a single contact about a host */ +int create_notification_list_from_host(host *,int,int *); /* given a host, create list of contacts to be notified (remove duplicates) */ +int create_notification_list_from_service(service *,int,int *); /* given a service, create list of contacts to be notified (remove duplicates) */ +int add_notification(contact *); /* adds a notification instance */ +notification *find_notification(contact *); /* finds a notification object */ +time_t get_next_host_notification_time(host *,time_t); /* calculates nex acceptable re-notification time for a host */ +time_t get_next_service_notification_time(service *,time_t); /* calculates nex acceptable re-notification time for a service */ + + +/**** Logging Functions ****/ +void logit(int,int,const char *, ...) + __attribute__((__format__(__printf__, 3, 4))); +int write_to_logs_and_console(char *,unsigned long,int); /* writes a string to screen and logs */ +int write_to_console(char *); /* writes a string to screen */ +int write_to_all_logs(char *,unsigned long); /* writes a string to main log file and syslog facility */ +int write_to_all_logs_with_timestamp(char *,unsigned long,time_t *); /* writes a string to main log file and syslog facility */ +int write_to_log(char *,unsigned long,time_t *); /* write a string to the main log file */ +int write_to_syslog(char *,unsigned long); /* write a string to the syslog facility */ +int log_service_event(service *); /* logs a service event */ +int log_host_event(host *); /* logs a host event */ +int log_host_states(int,time_t *); /* logs initial/current host states */ +int log_service_states(int,time_t *); /* logs initial/current service states */ +int rotate_log_file(time_t); /* rotates the main log file */ +int write_log_file_info(time_t *); /* records log file/version info */ +int open_debug_log(void); +int log_debug_info(int,int,const char *,...) + __attribute__((__format__(__printf__, 3, 4))); +int close_debug_log(void); + + +/**** Cleanup Functions ****/ +void cleanup(void); /* cleanup after ourselves (before quitting or restarting) */ +void free_memory(void); /* free memory allocated to all linked lists in memory */ +int reset_variables(void); /* reset all global variables */ +void free_notification_list(void); /* frees all memory allocated to the notification list */ + + +/**** Hash Functions ****/ +int hashfunc(const char *name1, const char *name2, int hashslots); +int compare_hashdata(const char *,const char *,const char *,const char *); + + +/**** Miscellaneous Functions ****/ +void sighandler(int); /* handles signals */ +void service_check_sighandler(int); /* handles timeouts when executing service checks */ +void host_check_sighandler(int); /* handles timeouts when executing host checks */ +void my_system_sighandler(int); /* handles timeouts when executing commands via my_system() */ +void file_lock_sighandler(int); /* handles timeouts while waiting for file locks */ +void strip(char *); /* strips whitespace from string */ +char *my_strtok(char *,char *); /* my replacement for strtok() function (doesn't skip consecutive tokens) */ +char *my_strsep(char **,const char *); /* Solaris doesn't have strsep(), so I took this from the glibc source code */ +#ifdef REMOVED_10182007 +int my_free(void **); /* my wrapper for free() */ +#endif +char *get_next_string_from_buf(char *buf, int *start_index, int bufsize); +int compare_strings(char *,char *); /* compares two strings for equality */ +char *escape_newlines(char *); +int contains_illegal_object_chars(char *); /* tests whether or not an object name (host, service, etc.) contains illegal characters */ +int my_rename(char *,char *); /* renames a file - works across filesystems */ +int my_fcopy(char *,char *); /* copies a file - works across filesystems */ +int get_raw_command_line(command *,char *,char **,int); /* given a raw command line, determine the actual command to run */ +int check_time_against_period(time_t,timeperiod *); /* check to see if a specific time is covered by a time period */ +int is_daterange_single_day(daterange *); +time_t calculate_time_from_weekday_of_month(int,int,int,int); /* calculates midnight time of specific (3rd, last, etc.) weekday of a particular month */ +time_t calculate_time_from_day_of_month(int,int,int); /* calculates midnight time of specific (1st, last, etc.) day of a particular month */ +void get_next_valid_time(time_t, time_t *,timeperiod *); /* get the next valid time in a time period */ +void get_datetime_string(time_t *,char *,int,int); /* get a date/time string for use in output */ +void get_time_breakdown(unsigned long,int *,int *,int *, int *); +time_t get_next_log_rotation_time(void); /* determine the next time to schedule a log rotation */ +int init_embedded_perl(char **); /* initialized embedded perl interpreter */ +int deinit_embedded_perl(void); /* cleans up embedded perl */ +int file_uses_embedded_perl(char *); /* tests whether or not the embedded perl interpreter should be used on a file */ +int dbuf_init(dbuf *,int); +int dbuf_free(dbuf *); +int dbuf_strcat(dbuf *,char *); +int set_environment_var(char *,char *,int); /* sets/clears and environment variable */ +int check_for_nagios_updates(int,int); /* checks to see if new version of Nagios are available */ +int query_update_api(void); /* checks to see if new version of Nagios are available */ + + +/**** External Command Functions ****/ +int check_for_external_commands(void); /* checks for any external commands */ +int process_external_command1(char *); /* top-level external command processor */ +int process_external_command2(int,time_t,char *); /* process an external command */ +int process_external_commands_from_file(char *,int); /* process external commands in a file */ +int process_host_command(int,time_t,char *); /* process an external host command */ +int process_hostgroup_command(int,time_t,char *); /* process an external hostgroup command */ +int process_service_command(int,time_t,char *); /* process an external service command */ +int process_servicegroup_command(int,time_t,char *); /* process an external servicegroup command */ +int process_contact_command(int,time_t,char *); /* process an external contact command */ +int process_contactgroup_command(int,time_t,char *); /* process an external contactgroup command */ + + +/**** External Command Implementations ****/ +int cmd_add_comment(int,time_t,char *); /* add a service or host comment */ +int cmd_delete_comment(int,char *); /* delete a service or host comment */ +int cmd_delete_all_comments(int,char *); /* delete all comments associated with a host or service */ +int cmd_delay_notification(int,char *); /* delay a service or host notification */ +int cmd_schedule_service_check(int,char *,int); /* schedule an immediate or delayed service check */ +int cmd_schedule_check(int,char *); /* schedule an immediate or delayed host check */ +int cmd_schedule_host_service_checks(int,char *,int); /* schedule an immediate or delayed checks of all services on a host */ +int cmd_signal_process(int,char *); /* schedules a program shutdown or restart */ +int cmd_process_service_check_result(int,time_t,char *); /* processes a passive service check */ +int cmd_process_host_check_result(int,time_t,char *); /* processes a passive host check */ +int cmd_acknowledge_problem(int,char *); /* acknowledges a host or service problem */ +int cmd_remove_acknowledgement(int,char *); /* removes a host or service acknowledgement */ +int cmd_schedule_downtime(int,time_t,char *); /* schedules host or service downtime */ +int cmd_delete_downtime(int,char *); /* cancels active/pending host or service scheduled downtime */ +int cmd_change_object_int_var(int,char *); /* changes host/svc (int) variable */ +int cmd_change_object_char_var(int,char *); /* changes host/svc (char) variable */ +int cmd_change_object_custom_var(int,char *); /* changes host/svc custom variable */ +int cmd_process_external_commands_from_file(int,char *); /* process external commands from a file */ + +int process_passive_service_check(time_t,char *,char *,int,char *); +int process_passive_host_check(time_t,char *,int,char *); + + +/**** Internal Command Implementations ****/ +void disable_service_checks(service *); /* disables a service check */ +void enable_service_checks(service *); /* enables a service check */ +void schedule_service_check(service *,time_t,int); /* schedules an immediate or delayed service check */ +void schedule_host_check(host *,time_t,int); /* schedules an immediate or delayed host check */ +void enable_all_notifications(void); /* enables notifications on a program-wide basis */ +void disable_all_notifications(void); /* disables notifications on a program-wide basis */ +void enable_service_notifications(service *); /* enables service notifications */ +void disable_service_notifications(service *); /* disables service notifications */ +void enable_host_notifications(host *); /* enables host notifications */ +void disable_host_notifications(host *); /* disables host notifications */ +void enable_and_propagate_notifications(host *,int,int,int,int); /* enables notifications for all hosts and services beyond a given host */ +void disable_and_propagate_notifications(host *,int,int,int,int); /* disables notifications for all hosts and services beyond a given host */ +void schedule_and_propagate_downtime(host *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long); /* schedules downtime for all hosts beyond a given host */ +void acknowledge_host_problem(host *,char *,char *,int,int,int); /* acknowledges a host problem */ +void acknowledge_service_problem(service *,char *,char *,int,int,int); /* acknowledges a service problem */ +void remove_host_acknowledgement(host *); /* removes a host acknowledgement */ +void remove_service_acknowledgement(service *); /* removes a service acknowledgement */ +void start_executing_service_checks(void); /* starts executing service checks */ +void stop_executing_service_checks(void); /* stops executing service checks */ +void start_accepting_passive_service_checks(void); /* starts accepting passive service check results */ +void stop_accepting_passive_service_checks(void); /* stops accepting passive service check results */ +void enable_passive_service_checks(service *); /* enables passive service checks for a particular service */ +void disable_passive_service_checks(service *); /* disables passive service checks for a particular service */ +void start_using_event_handlers(void); /* enables event handlers on a program-wide basis */ +void stop_using_event_handlers(void); /* disables event handlers on a program-wide basis */ +void enable_service_event_handler(service *); /* enables the event handler for a particular service */ +void disable_service_event_handler(service *); /* disables the event handler for a particular service */ +void enable_host_event_handler(host *); /* enables the event handler for a particular host */ +void disable_host_event_handler(host *); /* disables the event handler for a particular host */ +void enable_host_checks(host *); /* enables checks of a particular host */ +void disable_host_checks(host *); /* disables checks of a particular host */ +void start_obsessing_over_service_checks(void); /* start obsessing about service check results */ +void stop_obsessing_over_service_checks(void); /* stop obsessing about service check results */ +void start_obsessing_over_host_checks(void); /* start obsessing about host check results */ +void stop_obsessing_over_host_checks(void); /* stop obsessing about host check results */ +void enable_service_freshness_checks(void); /* enable service freshness checks */ +void disable_service_freshness_checks(void); /* disable service freshness checks */ +void enable_host_freshness_checks(void); /* enable host freshness checks */ +void disable_host_freshness_checks(void); /* disable host freshness checks */ +void process_passive_checks(void); /* processes passive host and service check results */ +void enable_all_failure_prediction(void); /* enables failure prediction on a program-wide basis */ +void disable_all_failure_prediction(void); /* disables failure prediction on a program-wide basis */ +void enable_performance_data(void); /* enables processing of performance data on a program-wide basis */ +void disable_performance_data(void); /* disables processing of performance data on a program-wide basis */ +void start_executing_host_checks(void); /* starts executing host checks */ +void stop_executing_host_checks(void); /* stops executing host checks */ +void start_accepting_passive_host_checks(void); /* starts accepting passive host check results */ +void stop_accepting_passive_host_checks(void); /* stops accepting passive host check results */ +void enable_passive_host_checks(host *); /* enables passive host checks for a particular host */ +void disable_passive_host_checks(host *); /* disables passive host checks for a particular host */ +void start_obsessing_over_service(service *); /* start obsessing about specific service check results */ +void stop_obsessing_over_service(service *); /* stop obsessing about specific service check results */ +void start_obsessing_over_host(host *); /* start obsessing about specific host check results */ +void stop_obsessing_over_host(host *); /* stop obsessing about specific host check results */ +void set_host_notification_number(host *,int); /* sets current notification number for a specific host */ +void set_service_notification_number(service *,int); /* sets current notification number for a specific service */ +void enable_contact_host_notifications(contact *); /* enables host notifications for a specific contact */ +void disable_contact_host_notifications(contact *); /* disables host notifications for a specific contact */ +void enable_contact_service_notifications(contact *); /* enables service notifications for a specific contact */ +void disable_contact_service_notifications(contact *); /* disables service notifications for a specific contact */ + +int init_check_result_worker_thread(void); +int shutdown_check_result_worker_thread(void); +void * check_result_worker_thread(void *); +void cleanup_check_result_worker_thread(void *); + +int init_command_file_worker_thread(void); +int shutdown_command_file_worker_thread(void); +void * command_file_worker_thread(void *); +void cleanup_command_file_worker_thread(void *); + +int submit_external_command(char *,int *); +int submit_raw_external_command(char *,time_t *,int *); + +char *get_program_version(void); +char *get_program_modification_date(void); + +mmapfile *mmap_fopen(char *); /* open a file read-only via mmap() */ +int mmap_fclose(mmapfile *); +char *mmap_fgets(mmapfile *); +char *mmap_fgets_multiline(mmapfile *); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/nagios/nebcallbacks.h b/nagios/nebcallbacks.h new file mode 100644 index 0000000..44d94ba --- /dev/null +++ b/nagios/nebcallbacks.h @@ -0,0 +1,89 @@ + +/***************************************************************************** + * + * NEBCALLBACKS.H - Include file for event broker modules + * + * Copyright (c) 2002-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 01-06-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBCALLBACKS_H +#define _NEBCALLBACKS_H + +#include "config.h" +#include "nebmodules.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/***** CALLBACK TYPES *****/ + +#define NEBCALLBACK_NUMITEMS 33 /* total number of callback types we have */ + +#define NEBCALLBACK_RESERVED0 0 /* reserved for future use */ +#define NEBCALLBACK_RESERVED1 1 +#define NEBCALLBACK_RESERVED2 2 +#define NEBCALLBACK_RESERVED3 3 +#define NEBCALLBACK_RESERVED4 4 + +#define NEBCALLBACK_RAW_DATA 5 +#define NEBCALLBACK_NEB_DATA 6 + +#define NEBCALLBACK_PROCESS_DATA 7 +#define NEBCALLBACK_TIMED_EVENT_DATA 8 +#define NEBCALLBACK_LOG_DATA 9 +#define NEBCALLBACK_SYSTEM_COMMAND_DATA 10 +#define NEBCALLBACK_EVENT_HANDLER_DATA 11 +#define NEBCALLBACK_NOTIFICATION_DATA 12 +#define NEBCALLBACK_SERVICE_CHECK_DATA 13 +#define NEBCALLBACK_HOST_CHECK_DATA 14 +#define NEBCALLBACK_COMMENT_DATA 15 +#define NEBCALLBACK_DOWNTIME_DATA 16 +#define NEBCALLBACK_FLAPPING_DATA 17 +#define NEBCALLBACK_PROGRAM_STATUS_DATA 18 +#define NEBCALLBACK_HOST_STATUS_DATA 19 +#define NEBCALLBACK_SERVICE_STATUS_DATA 20 +#define NEBCALLBACK_ADAPTIVE_PROGRAM_DATA 21 +#define NEBCALLBACK_ADAPTIVE_HOST_DATA 22 +#define NEBCALLBACK_ADAPTIVE_SERVICE_DATA 23 +#define NEBCALLBACK_EXTERNAL_COMMAND_DATA 24 +#define NEBCALLBACK_AGGREGATED_STATUS_DATA 25 +#define NEBCALLBACK_RETENTION_DATA 26 +#define NEBCALLBACK_CONTACT_NOTIFICATION_DATA 27 +#define NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA 28 +#define NEBCALLBACK_ACKNOWLEDGEMENT_DATA 29 +#define NEBCALLBACK_STATE_CHANGE_DATA 30 +#define NEBCALLBACK_CONTACT_STATUS_DATA 31 +#define NEBCALLBACK_ADAPTIVE_CONTACT_DATA 32 + + +/***** CALLBACK FUNCTIONS *****/ + +int neb_register_callback(int callback_type, void *mod_handle, int priority, int (*callback_func)(int,void *)); +int neb_deregister_callback(int callback_type, int (*callback_func)(int,void *)); +int neb_deregister_module_callbacks(nebmodule *); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/nagios/neberrors.h b/nagios/neberrors.h new file mode 100644 index 0000000..ec7ac61 --- /dev/null +++ b/nagios/neberrors.h @@ -0,0 +1,70 @@ + +/***************************************************************************** + * + * NEBERRORS.H - Event broker errors + * + * Copyright (c) 2003-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 12-12-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBERRORS_H +#define _NEBERRORS_H + + +/***** GENERIC DEFINES *****/ + +#define NEB_OK 0 +#define NEB_ERROR -1 + +#define NEB_TRUE 1 +#define NEB_FALSE 0 + + + +/***** GENERIC ERRORS *****/ + +#define NEBERROR_NOMEM 100 /* memory could not be allocated */ + + + +/***** CALLBACK ERRORS *****/ + +#define NEBERROR_NOCALLBACKFUNC 200 /* no callback function was specified */ +#define NEBERROR_NOCALLBACKLIST 201 /* callback list not initialized */ +#define NEBERROR_CALLBACKBOUNDS 202 /* callback type was out of bounds */ +#define NEBERROR_CALLBACKNOTFOUND 203 /* the callback could not be found */ +#define NEBERROR_NOMODULEHANDLE 204 /* no module handle specified */ +#define NEBERROR_BADMODULEHANDLE 205 /* bad module handle */ +#define NEBERROR_CALLBACKOVERRIDE 206 /* module wants to override default Nagios handling of event */ +#define NEBERROR_CALLBACKCANCEL 207 /* module wants to cancel callbacks to other modules */ + + + +/***** MODULE ERRORS *****/ + +#define NEBERROR_NOMODULE 300 /* no module was specified */ + + + +/***** MODULE INFO ERRORS *****/ + +#define NEBERROR_MODINFOBOUNDS 400 /* module info index was out of bounds */ + + +#endif diff --git a/nagios/nebmods.h b/nagios/nebmods.h new file mode 100644 index 0000000..b41d8ca --- /dev/null +++ b/nagios/nebmods.h @@ -0,0 +1,71 @@ + +/***************************************************************************** + * + * NEBMODS.H - Include file for event broker modules + * + * Copyright (c) 2002-2005 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-25-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBMODS_H +#define _NEBMODS_H + +#include "config.h" +#include "nebcallbacks.h" +#include "nebmodules.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/***** MODULE STRUCTURES *****/ + +/* NEB module callback list struct */ +typedef struct nebcallback_struct{ + void *callback_func; + void *module_handle; + int priority; + struct nebcallback_struct *next; + }nebcallback; + + + +/***** MODULE FUNCTIONS *****/ + +int neb_init_modules(void); +int neb_deinit_modules(void); +int neb_load_all_modules(void); +int neb_load_module(nebmodule *); +int neb_free_module_list(void); +int neb_unload_all_modules(int,int); +int neb_unload_module(nebmodule *,int,int); +int neb_add_module(char *,char *,int); + + +/***** CALLBACK FUNCTIONS *****/ +int neb_init_callback_list(void); +int neb_free_callback_list(void); +int neb_make_callbacks(int,void *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nagios/nebmodules.h b/nagios/nebmodules.h new file mode 100644 index 0000000..6b9a099 --- /dev/null +++ b/nagios/nebmodules.h @@ -0,0 +1,103 @@ + +/***************************************************************************** + * + * NEBMODULES.H - Include file for event broker modules + * + * Copyright (c) 2002-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 02-27-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBMODULES_H +#define _NEBMODULES_H + +#ifdef __cplusplus + extern "C" { +#endif + +/***** MODULE VERSION INFORMATION *****/ + +#define NEB_API_VERSION(x) int __neb_api_version = x; +#define CURRENT_NEB_API_VERSION 3 + + + +/***** MODULE INFORMATION *****/ + +#define NEBMODULE_MODINFO_NUMITEMS 6 +#define NEBMODULE_MODINFO_TITLE 0 +#define NEBMODULE_MODINFO_AUTHOR 1 +#define NEBMODULE_MODINFO_COPYRIGHT 2 +#define NEBMODULE_MODINFO_VERSION 3 +#define NEBMODULE_MODINFO_LICENSE 4 +#define NEBMODULE_MODINFO_DESC 5 + + + +/***** MODULE LOAD/UNLOAD OPTIONS *****/ + +#define NEBMODULE_NORMAL_LOAD 0 /* module is being loaded normally */ +#define NEBMODULE_REQUEST_UNLOAD 0 /* request module to unload (but don't force it) */ +#define NEBMODULE_FORCE_UNLOAD 1 /* force module to unload */ + + + +/***** MODULES UNLOAD REASONS *****/ + +#define NEBMODULE_NEB_SHUTDOWN 1 /* event broker is shutting down */ +#define NEBMODULE_NEB_RESTART 2 /* event broker is restarting */ +#define NEBMODULE_ERROR_NO_INIT 3 /* _module_init() function was not found in module */ +#define NEBMODULE_ERROR_BAD_INIT 4 /* _module_init() function returned a bad code */ +#define NEBMODULE_ERROR_API_VERSION 5 /* module version is incompatible with current api */ + + + +/***** MODULE STRUCTURES *****/ + +/* NEB module structure */ +typedef struct nebmodule_struct{ + char *filename; + char *args; + char *info[NEBMODULE_MODINFO_NUMITEMS]; + int should_be_loaded; + int is_currently_loaded; +#ifdef USE_LTDL + lt_dlhandle module_handle; + lt_ptr init_func; + lt_ptr deinit_func; +#else + void *module_handle; + void *init_func; + void *deinit_func; +#endif +#ifdef HAVE_PTHREAD_H + pthread_t thread_id; +#endif + struct nebmodule_struct *next; + }nebmodule; + + + +/***** MODULE FUNCTIONS *****/ +int neb_set_module_info(void *,int,char *); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/nebstructs.h b/nagios/nebstructs.h new file mode 100644 index 0000000..25fd1ca --- /dev/null +++ b/nagios/nebstructs.h @@ -0,0 +1,533 @@ + +/***************************************************************************** + * + * NEBSTRUCTS.H - Event broker includes for Nagios + * + * Copyright (c) 2003-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-28-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBSTRUCTS_H +#define _NEBSTRUCTS_H + +#include "config.h" +#include "objects.h" +#include "nagios.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/****** STRUCTURES *************************/ + +/* process data structure */ +typedef struct nebstruct_process_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + }nebstruct_process_data; + + +/* timed event data structure */ +typedef struct nebstruct_timed_event_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int event_type; + int recurring; + time_t run_time; + void *event_data; + + void *event_ptr; + }nebstruct_timed_event_data; + + +/* log data structure */ +typedef struct nebstruct_log_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t entry_time; + int data_type; + char *data; + }nebstruct_log_data; + + +/* system command structure */ +typedef struct nebstruct_system_command_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + struct timeval start_time; + struct timeval end_time; + int timeout; + char *command_line; + int early_timeout; + double execution_time; + int return_code; + char *output; + }nebstruct_system_command_data; + + +/* event handler structure */ +typedef struct nebstruct_event_handler_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int eventhandler_type; + char *host_name; + char *service_description; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + int return_code; + char *output; + + void *object_ptr; + }nebstruct_event_handler_data; + + +/* host check structure */ +typedef struct nebstruct_host_check_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + int current_attempt; + int check_type; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + + void *object_ptr; + }nebstruct_host_check_data; + + +/* service check structure */ +typedef struct nebstruct_service_check_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + char *service_description; + int check_type; + int current_attempt; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + + void *object_ptr; + }nebstruct_service_check_data; + + +/* comment data structure */ +typedef struct nebstruct_comment_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int comment_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + int persistent; + int source; + int entry_type; + int expires; + time_t expire_time; + unsigned long comment_id; + + void *object_ptr; /* not implemented yet */ + }nebstruct_comment_data; + + +/* downtime data structure */ +typedef struct nebstruct_downtime_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int downtime_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + time_t start_time; + time_t end_time; + int fixed; + unsigned long duration; + unsigned long triggered_by; + unsigned long downtime_id; + + void *object_ptr; /* not implemented yet */ + }nebstruct_downtime_data; + + +/* flapping data structure */ +typedef struct nebstruct_flapping_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int flapping_type; + char *host_name; + char *service_description; + double percent_change; + double high_threshold; + double low_threshold; + unsigned long comment_id; + + void *object_ptr; + }nebstruct_flapping_data; + + +/* program status structure */ +typedef struct nebstruct_program_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t program_start; + int pid; + int daemon_mode; + time_t last_command_check; + time_t last_log_rotation; + int notifications_enabled; + int active_service_checks_enabled; + int passive_service_checks_enabled; + int active_host_checks_enabled; + int passive_host_checks_enabled; + int event_handlers_enabled; + int flap_detection_enabled; + int failure_prediction_enabled; + int process_performance_data; + int obsess_over_hosts; + int obsess_over_services; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; + char *global_host_event_handler; + char *global_service_event_handler; + }nebstruct_program_status_data; + + +/* host status structure */ +typedef struct nebstruct_host_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + }nebstruct_host_status_data; + + +/* service status structure */ +typedef struct nebstruct_service_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + }nebstruct_service_status_data; + + +/* contact status structure */ +typedef struct nebstruct_contact_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + }nebstruct_contact_status_data; + + +/* notification data structure */ +typedef struct nebstruct_notification_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + int contacts_notified; + + void *object_ptr; + }nebstruct_notification_data; + + +/* contact notification data structure */ +typedef struct nebstruct_contact_notification_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + }nebstruct_contact_notification_data; + + +/* contact notification method data structure */ +typedef struct nebstruct_contact_notification_method_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + char *command_name; + char *command_args; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + }nebstruct_contact_notification_method_data; + + +/* adaptive program data structure */ +typedef struct nebstruct_adaptive_program_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + }nebstruct_adaptive_program_data; + + +/* adaptive host data structure */ +typedef struct nebstruct_adaptive_host_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + }nebstruct_adaptive_host_data; + + +/* adaptive service data structure */ +typedef struct nebstruct_adaptive_service_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + }nebstruct_adaptive_service_data; + + +/* adaptive contact data structure */ +typedef struct nebstruct_adaptive_contact_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + + void *object_ptr; + }nebstruct_adaptive_contact_data; + + +/* external command data structure */ +typedef struct nebstruct_external_command_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + time_t entry_time; + char *command_string; + char *command_args; + }nebstruct_external_command_data; + + +/* aggregated status data structure */ +typedef struct nebstruct_aggregated_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + }nebstruct_aggregated_status_data; + + +/* retention data structure */ +typedef struct nebstruct_retention_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + }nebstruct_retention_data; + + +/* acknowledgement structure */ +typedef struct nebstruct_acknowledgement_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int acknowledgement_type; + char *host_name; + char *service_description; + int state; + char *author_name; + char *comment_data; + int is_sticky; + int persistent_comment; + int notify_contacts; + + void *object_ptr; + }nebstruct_acknowledgement_data; + + +/* state change structure */ +typedef struct nebstruct_statechange_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int statechange_type; + char *host_name; + char *service_description; + int state; + int state_type; + int current_attempt; + int max_attempts; + char *output; + + void *object_ptr; + }nebstruct_statechange_data; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/objects.h b/nagios/objects.h new file mode 100644 index 0000000..7851ef6 --- /dev/null +++ b/nagios/objects.h @@ -0,0 +1,771 @@ + +/***************************************************************************** + * + * OBJECTS.H - Header file for object addition/search functions + * + * Copyright (c) 1999-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-10-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _OBJECTS_H +#define _OBJECTS_H + +#include "config.h" +#include "common.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/*************** CURRENT OBJECT REVISION **************/ + +#define CURRENT_OBJECT_STRUCTURE_VERSION 307 /* increment when changes are made to data structures... */ + /* Nagios 3 starts at 300, Nagios 4 at 400, etc. */ + + + +/***************** OBJECT SIZE LIMITS *****************/ + +#define MAX_STATE_HISTORY_ENTRIES 21 /* max number of old states to keep track of for flap detection */ +#define MAX_CONTACT_ADDRESSES 6 /* max number of custom addresses a contact can have */ + + + +/***************** SKIP LISTS ****************/ + +#define NUM_OBJECT_SKIPLISTS 12 + +#define HOST_SKIPLIST 0 +#define SERVICE_SKIPLIST 1 +#define COMMAND_SKIPLIST 2 +#define TIMEPERIOD_SKIPLIST 3 +#define CONTACT_SKIPLIST 4 +#define CONTACTGROUP_SKIPLIST 5 +#define HOSTGROUP_SKIPLIST 6 +#define SERVICEGROUP_SKIPLIST 7 +#define HOSTDEPENDENCY_SKIPLIST 8 +#define SERVICEDEPENDENCY_SKIPLIST 9 +#define HOSTESCALATION_SKIPLIST 10 +#define SERVICEESCALATION_SKIPLIST 11 + + +/****************** DATA STRUCTURES *******************/ + +typedef struct host_struct host; +typedef struct service_struct service; +typedef struct contact_struct contact; + +/* OBJECT LIST STRUCTURE */ +typedef struct objectlist_struct{ + void *object_ptr; + struct objectlist_struct *next; + }objectlist; + + +/* TIMERANGE structure */ +typedef struct timerange_struct{ + unsigned long range_start; + unsigned long range_end; + struct timerange_struct *next; + }timerange; + + +/* DATERANGE structure */ +typedef struct daterange_struct{ + int type; + int syear; /* start year */ + int smon; /* start month */ + int smday; /* start day of month (may 3rd, last day in feb) */ + int swday; /* start day of week (thursday) */ + int swday_offset; /* start weekday offset (3rd thursday, last monday in jan) */ + int eyear; + int emon; + int emday; + int ewday; + int ewday_offset; + int skip_interval; + timerange *times; + struct daterange_struct *next; + }daterange; + + +/* TIMEPERIODEXCLUSION structure */ +typedef struct timeperiodexclusion_struct{ + char *timeperiod_name; + struct timeperiod_struct *timeperiod_ptr; + struct timeperiodexclusion_struct *next; + }timeperiodexclusion; + + +/* TIMEPERIOD structure */ +typedef struct timeperiod_struct{ + char *name; + char *alias; + timerange *days[7]; + daterange *exceptions[DATERANGE_TYPES]; + timeperiodexclusion *exclusions; + struct timeperiod_struct *next; + struct timeperiod_struct *nexthash; + }timeperiod; + + +/* CONTACTSMEMBER structure */ +typedef struct contactsmember_struct{ + char *contact_name; +#ifdef NSCORE + contact *contact_ptr; +#endif + struct contactsmember_struct *next; + }contactsmember; + + +/* CONTACTGROUP structure */ +typedef struct contactgroup_struct{ + char *group_name; + char *alias; + contactsmember *members; + struct contactgroup_struct *next; + struct contactgroup_struct *nexthash; + }contactgroup; + + +/* CONTACTGROUPSMEMBER structure */ +typedef struct contactgroupsmember_struct{ + char *group_name; +#ifdef NSCORE + contactgroup *group_ptr; +#endif + struct contactgroupsmember_struct *next; + }contactgroupsmember; + + +/* CUSTOMVARIABLESMEMBER structure */ +typedef struct customvariablesmember_struct{ + char *variable_name; + char *variable_value; + int has_been_modified; + struct customvariablesmember_struct *next; + }customvariablesmember; + + +/* COMMAND structure */ +typedef struct command_struct{ + char *name; + char *command_line; + struct command_struct *next; + struct command_struct *nexthash; + }command; + + +/* COMMANDSMEMBER structure */ +typedef struct commandsmember_struct{ + char *command_dummy; +#ifdef NSCORE + command *command_ptr; +#endif + struct commandsmember_struct *next; + }commandsmember; + + +/* CONTACT structure */ +struct contact_struct{ + char *name; + char *alias; + char *email; + char *pager; + char *address[MAX_CONTACT_ADDRESSES]; + commandsmember *host_notification_commands; + commandsmember *service_notification_commands; + int notify_on_service_unknown; + int notify_on_service_warning; + int notify_on_service_critical; + int notify_on_service_recovery; + int notify_on_service_flapping; + int notify_on_service_downtime; + int notify_on_host_down; + int notify_on_host_unreachable; + int notify_on_host_recovery; + int notify_on_host_flapping; + int notify_on_host_downtime; + char *host_notification_period; + char *service_notification_period; + int host_notifications_enabled; + int service_notifications_enabled; + int can_submit_commands; + int retain_status_information; + int retain_nonstatus_information; + customvariablesmember *custom_variables; +#ifdef NSCORE + time_t last_host_notification; + time_t last_service_notification; + unsigned long modified_attributes; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; + + timeperiod *host_notification_period_ptr; + timeperiod *service_notification_period_ptr; + objectlist *contactgroups_ptr; +#endif + struct contact_struct *next; + struct contact_struct *nexthash; + }; + + +/* SERVICESMEMBER structure */ +typedef struct servicesmember_struct{ + char *host_name; + char *service_description; +#ifdef NSCORE + service *service_ptr; +#endif + struct servicesmember_struct *next; + }servicesmember; + + +/* HOSTSMEMBER structure */ +typedef struct hostsmember_struct{ + char *host_name; +#ifdef NSCORE + host *host_ptr; +#endif + struct hostsmember_struct *next; + }hostsmember; + + +/* HOSTGROUP structure */ +typedef struct hostgroup_struct{ + char *group_name; + char *alias; + hostsmember *members; + char *notes; + char *notes_url; + char *action_url; + struct hostgroup_struct *next; + struct hostgroup_struct *nexthash; + }hostgroup; + + +/* HOST structure */ +struct host_struct{ + char *name; + char *display_name; + char *alias; + char *address; + hostsmember *parent_hosts; + hostsmember *child_hosts; + servicesmember *services; + char *host_check_command; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + char *event_handler; + contactgroupsmember *contact_groups; + contactsmember *contacts; + double notification_interval; + double first_notification_delay; + int notify_on_down; + int notify_on_unreachable; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_on_up; + int flap_detection_on_down; + int flap_detection_on_unreachable; + int stalk_on_up; + int stalk_on_down; + int stalk_on_unreachable; + int check_freshness; + int freshness_threshold; + int process_performance_data; + int checks_enabled; + int accept_passive_host_checks; + int event_handler_enabled; + int retain_status_information; + int retain_nonstatus_information; + int failure_prediction_enabled; + char *failure_prediction_options; + int obsess_over_host; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + char *vrml_image; + char *statusmap_image; + int have_2d_coords; + int x_2d; + int y_2d; + int have_3d_coords; + double x_3d; + double y_3d; + double z_3d; + int should_be_drawn; + customvariablesmember *custom_variables; +#ifdef NSCORE + int problem_has_been_acknowledged; + int acknowledgement_type; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int notifications_enabled; + time_t last_host_notification; + time_t next_host_notification; + time_t next_check; + int should_be_scheduled; + time_t last_check; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_up; + time_t last_time_down; + time_t last_time_unreachable; + int has_been_checked; + int is_being_freshened; + int notified_on_down; + int notified_on_unreachable; + int current_notification_number; + int no_more_notifications; + unsigned long current_notification_id; + int check_flapping_recovery_notification; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + time_t last_state_history_update; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + int total_services; + unsigned long total_service_check_interval; + unsigned long modified_attributes; + int circular_path_checked; + int contains_circular_path; + + command *event_handler_ptr; + command *check_command_ptr; + timeperiod *check_period_ptr; + timeperiod *notification_period_ptr; + objectlist *hostgroups_ptr; +#endif + struct host_struct *next; + struct host_struct *nexthash; + }; + + +/* SERVICEGROUP structure */ +typedef struct servicegroup_struct{ + char *group_name; + char *alias; + servicesmember *members; + char *notes; + char *notes_url; + char *action_url; + struct servicegroup_struct *next; + struct servicegroup_struct *nexthash; + }servicegroup; + + +/* SERVICE structure */ +struct service_struct{ + char *host_name; + char *description; + char *display_name; + char *service_check_command; + char *event_handler; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + int parallelize; + contactgroupsmember *contact_groups; + contactsmember *contacts; + double notification_interval; + double first_notification_delay; + int notify_on_unknown; + int notify_on_warning; + int notify_on_critical; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + int stalk_on_ok; + int stalk_on_warning; + int stalk_on_unknown; + int stalk_on_critical; + int is_volatile; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_on_ok; + int flap_detection_on_warning; + int flap_detection_on_unknown; + int flap_detection_on_critical; + int process_performance_data; + int check_freshness; + int freshness_threshold; + int accept_passive_service_checks; + int event_handler_enabled; + int checks_enabled; + int retain_status_information; + int retain_nonstatus_information; + int notifications_enabled; + int obsess_over_service; + int failure_prediction_enabled; + char *failure_prediction_options; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + customvariablesmember *custom_variables; +#ifdef NSCORE + int problem_has_been_acknowledged; + int acknowledgement_type; + int host_problem_at_last_check; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + time_t next_check; + int should_be_scheduled; + time_t last_check; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int check_flapping_recovery_notification; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_ok; + time_t last_time_warning; + time_t last_time_unknown; + time_t last_time_critical; + int has_been_checked; + int is_being_freshened; + int notified_on_unknown; + int notified_on_warning; + int notified_on_critical; + int current_notification_number; + unsigned long current_notification_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + unsigned long modified_attributes; + + host *host_ptr; + command *event_handler_ptr; + char *event_handler_args; + command *check_command_ptr; + char *check_command_args; + timeperiod *check_period_ptr; + timeperiod *notification_period_ptr; + objectlist *servicegroups_ptr; +#endif + struct service_struct *next; + struct service_struct *nexthash; + }; + + +/* SERVICE ESCALATION structure */ +typedef struct serviceescalation_struct{ + char *host_name; + char *description; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_recovery; + int escalate_on_warning; + int escalate_on_unknown; + int escalate_on_critical; + contactgroupsmember *contact_groups; + contactsmember *contacts; +#ifdef NSCORE + service *service_ptr; + timeperiod *escalation_period_ptr; +#endif + struct serviceescalation_struct *next; + struct serviceescalation_struct *nexthash; + }serviceescalation; + + +/* SERVICE DEPENDENCY structure */ +typedef struct servicedependency_struct{ + int dependency_type; + char *dependent_host_name; + char *dependent_service_description; + char *host_name; + char *service_description; + char *dependency_period; + int inherits_parent; + int fail_on_ok; + int fail_on_warning; + int fail_on_unknown; + int fail_on_critical; + int fail_on_pending; +#ifdef NSCORE + int circular_path_checked; + int contains_circular_path; + + service *master_service_ptr; + service *dependent_service_ptr; + timeperiod *dependency_period_ptr; +#endif + struct servicedependency_struct *next; + struct servicedependency_struct *nexthash; + }servicedependency; + + +/* HOST ESCALATION structure */ +typedef struct hostescalation_struct{ + char *host_name; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_recovery; + int escalate_on_down; + int escalate_on_unreachable; + contactgroupsmember *contact_groups; + contactsmember *contacts; +#ifdef NSCORE + host *host_ptr; + timeperiod *escalation_period_ptr; +#endif + struct hostescalation_struct *next; + struct hostescalation_struct *nexthash; + }hostescalation; + + +/* HOST DEPENDENCY structure */ +typedef struct hostdependency_struct{ + int dependency_type; + char *dependent_host_name; + char *host_name; + char *dependency_period; + int inherits_parent; + int fail_on_up; + int fail_on_down; + int fail_on_unreachable; + int fail_on_pending; +#ifdef NSCORE + int circular_path_checked; + int contains_circular_path; + + host *master_host_ptr; + host *dependent_host_ptr; + timeperiod *dependency_period_ptr; +#endif + struct hostdependency_struct *next; + struct hostdependency_struct *nexthash; + }hostdependency; + + + + +/****************** HASH STRUCTURES ********************/ + +typedef struct host_cursor_struct{ + int host_hashchain_iterator; + host *current_host_pointer; + }host_cursor; + + + + + +/********************* FUNCTIONS **********************/ + +/**** Top-level input functions ****/ +int read_object_config_data(char *,int,int,int); /* reads all external configuration data of specific types */ + + +/**** Object Creation Functions ****/ +contact *add_contact(char *,char *,char *,char *,char **,char *,char *,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int); /* adds a contact definition */ +commandsmember *add_service_notification_command_to_contact(contact *,char *); /* adds a service notification command to a contact definition */ +commandsmember *add_host_notification_command_to_contact(contact *,char *); /* adds a host notification command to a contact definition */ +customvariablesmember *add_custom_variable_to_contact(contact *,char *,char *); /* adds a custom variable to a service definition */ +host *add_host(char *,char *,char *,char *,char *,int,double,double,int,int,int,int,int,int,double,double,char *,int,char *,int,int,char *,int,int,double,double,int,int,int,int,int,int,int,int,char *,int,int,char *,char *,char *,char *,char *,char *,char *,int,int,int,double,double,double,int,int,int,int,int); /* adds a host definition */ +hostsmember *add_parent_host_to_host(host *,char *); /* adds a parent host to a host definition */ +hostsmember *add_child_link_to_host(host *,host *); /* adds a child host to a host definition */ +contactgroupsmember *add_contactgroup_to_host(host *,char *); /* adds a contactgroup to a host definition */ +contactsmember *add_contact_to_host(host *,char *); /* adds a contact to a host definition */ +customvariablesmember *add_custom_variable_to_host(host *,char *,char *); /* adds a custom variable to a host definition */ +timeperiod *add_timeperiod(char *,char *); /* adds a timeperiod definition */ +timeperiodexclusion *add_exclusion_to_timeperiod(timeperiod *,char *); /* adds an exclusion to a timeperiod */ +timerange *add_timerange_to_timeperiod(timeperiod *,int,unsigned long,unsigned long); /* adds a timerange to a timeperiod definition */ +daterange *add_exception_to_timeperiod(timeperiod *,int,int,int,int,int,int,int,int,int,int,int,int); +timerange *add_timerange_to_daterange(daterange *,unsigned long,unsigned long); +hostgroup *add_hostgroup(char *,char *,char *,char *,char *); /* adds a hostgroup definition */ +hostsmember *add_host_to_hostgroup(hostgroup *, char *); /* adds a host to a hostgroup definition */ +servicegroup *add_servicegroup(char *,char *,char *,char *,char *); /* adds a servicegroup definition */ +servicesmember *add_service_to_servicegroup(servicegroup *,char *,char *); /* adds a service to a servicegroup definition */ +contactgroup *add_contactgroup(char *,char *); /* adds a contactgroup definition */ +contactsmember *add_contact_to_contactgroup(contactgroup *,char *); /* adds a contact to a contact group definition */ +command *add_command(char *,char *); /* adds a command definition */ +service *add_service(char *,char *,char *,char *,int,int,int,int,double,double,double,double,char *,int,int,int,int,int,int,int,int,char *,int,char *,int,int,double,double,int,int,int,int,int,int,int,int,int,int,char *,int,int,char *,char *,char *,char *,char *,int,int,int); /* adds a service definition */ +contactgroupsmember *add_contactgroup_to_service(service *,char *); /* adds a contact group to a service definition */ +contactsmember *add_contact_to_service(service *,char *); /* adds a contact to a host definition */ +serviceescalation *add_serviceescalation(char *,char *,int,int,double,char *,int,int,int,int); /* adds a service escalation definition */ +contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *,char *); /* adds a contact group to a service escalation definition */ +contactsmember *add_contact_to_serviceescalation(serviceescalation *,char *); /* adds a contact to a service escalation definition */ +customvariablesmember *add_custom_variable_to_service(service *,char *,char *); /* adds a custom variable to a service definition */ +servicedependency *add_service_dependency(char *,char *,char *,char *,int,int,int,int,int,int,int,char *); /* adds a service dependency definition */ +hostdependency *add_host_dependency(char *,char *,int,int,int,int,int,int,char *); /* adds a host dependency definition */ +hostescalation *add_hostescalation(char *,int,int,double,char *,int,int,int); /* adds a host escalation definition */ +contactsmember *add_contact_to_hostescalation(hostescalation *,char *); /* adds a contact to a host escalation definition */ +contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *,char *); /* adds a contact group to a host escalation definition */ + +contactsmember *add_contact_to_object(contactsmember **,char *); /* adds a contact to an object */ +customvariablesmember *add_custom_variable_to_object(customvariablesmember **,char *,char *); /* adds a custom variable to an object */ + + +servicesmember *add_service_link_to_host(host *,service *); + + +/*** Object Skiplist Functions ****/ +int init_object_skiplists(void); +int free_object_skiplists(void); +int skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b); +int skiplist_compare_host(void *a, void *b); +int skiplist_compare_service(void *a, void *b); +int skiplist_compare_command(void *a, void *b); +int skiplist_compare_timeperiod(void *a, void *b); +int skiplist_compare_contact(void *a, void *b); +int skiplist_compare_contactgroup(void *a, void *b); +int skiplist_compare_hostgroup(void *a, void *b); +int skiplist_compare_servicegroup(void *a, void *b); +int skiplist_compare_hostescalation(void *a, void *b); +int skiplist_compare_serviceescalation(void *a, void *b); +int skiplist_compare_hostdependency(void *a, void *b); +int skiplist_compare_servicedependency(void *a, void *b); + +int get_host_count(void); +int get_service_count(void); + + + +/**** Object Hash Functions ****/ +int add_servicedependency_to_hashlist(servicedependency *); + + +/**** Object Search Functions ****/ +timeperiod * find_timeperiod(char *); /* finds a timeperiod object */ +host * find_host(char *); /* finds a host object */ +hostgroup * find_hostgroup(char *); /* finds a hostgroup object */ +servicegroup * find_servicegroup(char *); /* finds a servicegroup object */ +contact * find_contact(char *); /* finds a contact object */ +contactgroup * find_contactgroup(char *); /* finds a contactgroup object */ +command * find_command(char *); /* finds a command object */ +service * find_service(char *,char *); /* finds a service object */ + + +/**** Object Traversal Functions ****/ +hostescalation *get_first_hostescalation_by_host(char *, void **); +hostescalation *get_next_hostescalation_by_host(char *,void **); +serviceescalation *get_first_serviceescalation_by_service(char *,char *, void **); +serviceescalation *get_next_serviceescalation_by_service(char *,char *,void **); +hostdependency *get_first_hostdependency_by_dependent_host(char *, void **); +hostdependency *get_next_hostdependency_by_dependent_host(char *, void **); +servicedependency *get_first_servicedependency_by_dependent_service(char *,char *, void **); +servicedependency *get_next_servicedependency_by_dependent_service(char *,char *,void **); + +#ifdef NSCORE +int add_object_to_objectlist(objectlist **,void *); +int free_objectlist(objectlist **); +#endif + + +/**** Object Query Functions ****/ +int is_host_immediate_child_of_host(host *,host *); /* checks if a host is an immediate child of another host */ +int is_host_primary_immediate_child_of_host(host *,host *); /* checks if a host is an immediate child (and primary child) of another host */ +int is_host_immediate_parent_of_host(host *,host *); /* checks if a host is an immediate child of another host */ +int is_host_member_of_hostgroup(hostgroup *,host *); /* tests whether or not a host is a member of a specific hostgroup */ +int is_host_member_of_servicegroup(servicegroup *,host *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_service_member_of_servicegroup(servicegroup *,service *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_contact_member_of_contactgroup(contactgroup *, contact *); /* tests whether or not a contact is a member of a specific contact group */ +int is_contact_for_hostgroup(hostgroup *,contact *); /* tests whether or not a contact is a member of a specific hostgroup */ +int is_contact_for_servicegroup(servicegroup *,contact *); /* tests whether or not a contact is a member of a specific servicegroup */ +int is_contact_for_host(host *,contact *); /* tests whether or not a contact is a contact member for a specific host */ +int is_escalated_contact_for_host(host *,contact *); /* checks whether or not a contact is an escalated contact for a specific host */ +int is_contact_for_service(service *,contact *); /* tests whether or not a contact is a contact member for a specific service */ +int is_escalated_contact_for_service(service *,contact *); /* checks whether or not a contact is an escalated contact for a specific service */ +int is_host_immediate_parent_of_host(host *,host *); /* tests whether or not a host is an immediate parent of another host */ + +int number_of_immediate_child_hosts(host *); /* counts the number of immediate child hosts for a particular host */ +int number_of_total_child_hosts(host *); /* counts the number of total child hosts for a particular host */ +int number_of_immediate_parent_hosts(host *); /* counts the number of immediate parents hosts for a particular host */ +int number_of_total_parent_hosts(host *); /* counts the number of total parents hosts for a particular host */ + +#ifdef NSCORE +int check_for_circular_servicedependency_path(servicedependency *,servicedependency *,int); /* checks if a circular dependency exists for a given service */ +int check_for_circular_hostdependency_path(hostdependency *,hostdependency *,int); /* checks if a circular dependency exists for a given host */ +#endif + + +/**** Object Cleanup Functions ****/ +int free_object_data(void); /* frees all allocated memory for the object definitions */ + + + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/perfdata.h b/nagios/perfdata.h new file mode 100644 index 0000000..763ca4e --- /dev/null +++ b/nagios/perfdata.h @@ -0,0 +1,45 @@ + +/***************************************************************************** + * + * PERFDATA.H - Include file for performance data routines + * + * Copyright (c) 2001-2005 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 11-25-2005 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _PERFDATA_H +#define _PERFDATA_H + +#include "objects.h" + +#ifdef __cplusplus + extern "C" { +#endif + +int initialize_performance_data(char *); /* initializes performance data */ +int cleanup_performance_data(char *); /* cleans up performance data */ + +int update_host_performance_data(host *); /* updates host performance data */ +int update_service_performance_data(service *); /* updates service performance data */ + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios/skiplist.h b/nagios/skiplist.h new file mode 100644 index 0000000..96c61f5 --- /dev/null +++ b/nagios/skiplist.h @@ -0,0 +1,68 @@ + +/************************************************************************ + * + * SKIPLIST.H - Skiplist data structures and functions + * + * Copyright (c) 2008 Ethan Galstad + * Last Modified: 02-24-2008 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _SKIPLIST_H +#define _SKIPLIST_H + +#define SKIPLIST_OK 0 +#define SKIPLIST_ERROR_ARGS 1 +#define SKIPLIST_ERROR_MEMORY 2 +#define SKIPLIST_ERROR_DUPLICATE 3 + + +typedef struct skiplistnode_struct{ + void *data; + struct skiplistnode_struct *forward[1]; /* this must be the last element of the struct, as we allocate # of elements during runtime*/ +}skiplistnode; + +typedef struct skiplist_struct{ + int current_level; + int max_levels; + float level_probability; + unsigned long items; + int allow_duplicates; + int append_duplicates; + int (*compare_function)(void *,void *); + skiplistnode *head; +}skiplist; + + +skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *,void *)); +skiplistnode *skiplist_new_node(skiplist *list,int node_levels); +int skiplist_insert(skiplist *list, void *data); +int skiplist_random_level(skiplist *list); +int skiplist_empty(skiplist *list); +int skiplist_free(skiplist **list); +void *skiplist_peek(skiplist *); +void *skiplist_pop(skiplist *); +void *skiplist_get_first(skiplist *list, void **node_ptr); +void *skiplist_get_next(void **node_ptr); +void *skiplist_find_first(skiplist *list, void *data, void **node_ptr); +void *skiplist_find_next(skiplist *list, void *data, void **node_ptr); +int skiplist_delete(skiplist *list, void *data); +int skiplist_delete_first(skiplist *list, void *data); +int skiplist_delete_all(skiplist *list, void *data); +int skiplist_delete_node(skiplist *list, void *node_ptr); + +#endif diff --git a/nagios/sretention.h b/nagios/sretention.h new file mode 100644 index 0000000..5286061 --- /dev/null +++ b/nagios/sretention.h @@ -0,0 +1,37 @@ + +/***************************************************************************** + * + * SRETENTION.H - Header for state retention routines + * + * Copyright (c) 1999-2006 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 02-28-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifdef __cplusplus + extern "C" { +#endif + +int initialize_retention_data(char *); +int cleanup_retention_data(char *); +int save_state_information(int); /* saves all host and state information */ +int read_initial_state_information(void); /* reads in initial host and state information */ + +#ifdef __cplusplus + } +#endif diff --git a/nagios/statusdata.h b/nagios/statusdata.h new file mode 100644 index 0000000..caa94f8 --- /dev/null +++ b/nagios/statusdata.h @@ -0,0 +1,202 @@ + +/***************************************************************************** + * + * STATUSDATA.H - Header for external status data routines + * + * Copyright (c) 2000-2007 Ethan Galstad (egalstad@nagios.org) + * Last Modified: 10-19-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _STATUSDATA_H +#define _STATUSDATA_H + +#ifdef NSCORE +#include "objects.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef NSCGI + +#define READ_PROGRAM_STATUS 1 +#define READ_HOST_STATUS 2 +#define READ_SERVICE_STATUS 4 +#define READ_CONTACT_STATUS 8 + +#define READ_ALL_STATUS_DATA READ_PROGRAM_STATUS | READ_HOST_STATUS | READ_SERVICE_STATUS | READ_CONTACT_STATUS + + + +/*************************** CHAINED HASH LIMITS ***************************/ + +#define SERVICESTATUS_HASHSLOTS 1024 +#define HOSTSTATUS_HASHSLOTS 1024 + + +/**************************** DATA STRUCTURES ******************************/ + + +/* HOST STATUS structure */ +typedef struct hoststatus_struct{ + char *host_name; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int status; + time_t last_update; + int has_been_checked; + int should_be_scheduled; + int current_attempt; + int max_attempts; + time_t last_check; + time_t next_check; + int check_options; + int check_type; + time_t last_state_change; + time_t last_hard_state_change; + int last_hard_state; + time_t last_time_up; + time_t last_time_down; + time_t last_time_unreachable; + int state_type; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int notifications_enabled; + int problem_has_been_acknowledged; + int acknowledgement_type; + int current_notification_number; + int accept_passive_host_checks; + int event_handler_enabled; + int checks_enabled; + int flap_detection_enabled; + int is_flapping; + double percent_state_change; + double latency; + double execution_time; + int scheduled_downtime_depth; + int failure_prediction_enabled; + int process_performance_data; + int obsess_over_host; + struct hoststatus_struct *next; + struct hoststatus_struct *nexthash; + }hoststatus; + + +/* SERVICE STATUS structure */ +typedef struct servicestatus_struct{ + char *host_name; + char *description; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int max_attempts; + int current_attempt; + int status; + time_t last_update; + int has_been_checked; + int should_be_scheduled; + time_t last_check; + time_t next_check; + int check_options; + int check_type; + int checks_enabled; + time_t last_state_change; + time_t last_hard_state_change; + int last_hard_state; + time_t last_time_ok; + time_t last_time_warning; + time_t last_time_unknown; + time_t last_time_critical; + int state_type; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int notifications_enabled; + int problem_has_been_acknowledged; + int acknowledgement_type; + int current_notification_number; + int accept_passive_service_checks; + int event_handler_enabled; + int flap_detection_enabled; + int is_flapping; + double percent_state_change; + double latency; + double execution_time; + int scheduled_downtime_depth; + int failure_prediction_enabled; + int process_performance_data; + int obsess_over_service; + struct servicestatus_struct *next; + struct servicestatus_struct *nexthash; + }servicestatus; + + +/*************************** SERVICE STATES ***************************/ + +#define SERVICE_PENDING 1 +#define SERVICE_OK 2 +#define SERVICE_WARNING 4 +#define SERVICE_UNKNOWN 8 +#define SERVICE_CRITICAL 16 + + + +/**************************** HOST STATES ****************************/ + +#define HOST_PENDING 1 +#define HOST_UP 2 +#define HOST_DOWN 4 +#define HOST_UNREACHABLE 8 + + + +/**************************** FUNCTIONS ******************************/ + +int read_status_data(char *,int); /* reads all status data */ +int add_host_status(hoststatus *); /* adds a host status entry to the list in memory */ +int add_service_status(servicestatus *); /* adds a service status entry to the list in memory */ + +int add_hoststatus_to_hashlist(hoststatus *); +int add_servicestatus_to_hashlist(servicestatus *); + +servicestatus *find_servicestatus(char *,char *); /* finds status information for a specific service */ +hoststatus *find_hoststatus(char *); /* finds status information for a specific host */ +int get_servicestatus_count(char *,int); /* gets total number of services of a certain type for a specific host */ + +void free_status_data(void); /* free all memory allocated to status data */ +#endif + +#ifdef NSCORE +int initialize_status_data(char *); /* initializes status data at program start */ +int update_all_status_data(void); /* updates all status data */ +int cleanup_status_data(char *,int); /* cleans up status data at program termination */ +int update_program_status(int); /* updates program status data */ +int update_host_status(host *,int); /* updates host status data */ +int update_service_status(service *,int); /* updates service status data */ +int update_contact_status(contact *,int); /* updates contact status data */ +#endif + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/nagios4/README b/nagios4/README new file mode 100644 index 0000000..7bf3998 --- /dev/null +++ b/nagios4/README @@ -0,0 +1 @@ +These files are taken directly from Nagios 4.0.2. diff --git a/nagios4/bitmap.h b/nagios4/bitmap.h new file mode 100644 index 0000000..b729628 --- /dev/null +++ b/nagios4/bitmap.h @@ -0,0 +1,156 @@ +#ifndef LIBNAGIOS_bitmap_h__ +#define LIBNAGIOS_bitmap_h__ + +/** + * @file bitmap.h + * @brief Bit map API + * + * The bitmap api is useful for running set operations on objects + * indexed by unsigned integers. + * @{ + */ +struct bitmap; +typedef struct bitmap bitmap; + +/** + * Resize a bitmap + * If the bitmap is made smaller, data will silently be lost. + * + * @param bm The bitmap to resize + * @param size The new desired size of the bitmap + * @return 0 on success, -1 on errors. + */ +extern int bitmap_resize(bitmap *bm, unsigned long size); + +/** + * Create a bitmaptor of size 'size' + * @param size Desired storage capacity + * @return A bitmap pointer on success, NULL on errors + */ +extern bitmap *bitmap_create(unsigned long size); + +/** + * Destroy a bitmaptor by freeing all the memory it uses + * @param bm The bitmaptor to destroy + */ +extern void bitmap_destroy(bitmap *bm); + +/** + * Copy a bitmaptor + * @param bm The bitmaptor to copy + * @return Pointer to an identical bitmap on success, NULL on errors + */ +extern bitmap *bitmap_copy(const bitmap *bm); + +/** + * Set a bit in the map + * @param bm The bitmaptor to operate on + * @param pos Position of the bit to set + * @return 0 on success, -1 on errors + */ +extern int bitmap_set(bitmap *bm, unsigned long pos); + +/** + * Check if a particular bit is set in the map + * @param bm The bitmaptor to check + * @param pos Position of the bit to check + * @return 1 if set, otherwise 0 + */ +extern int bitmap_isset(const bitmap *bm, unsigned long pos); + +/** + * Unset a particular bit in the map + * @param bm The bitmaptor to operate on + * @param pos Position of the bit to unset + */ +extern int bitmap_unset(bitmap *bm, unsigned long pos); + +/** + * Obtain cardinality (max number of elements) of the bitmaptor + * @param bm The bitmaptor to check + * @return The cardinality of the bitmaptor + */ +extern unsigned long bitmap_cardinality(const bitmap *bm); +#define bitmap_size bitmap_cardinality + +/** + * Count set bits in map. Completed in O(n/8) time. + * @param bm The bitmaptor to count bits in + * @return The number of set bits + */ +extern unsigned long bitmap_count_set_bits(const bitmap *bm); + +/** + * Count unset bits in map. Completed in O(n/8) time. + * @param bm The bitmaptor to count bits in + * @return The number of set bits + */ +extern unsigned long bitmap_count_unset_bits(const bitmap *bm); + +/** + * Unset all bits in a bitmap + * @param bm The bitmap to clear + */ +extern void bitmap_clear(bitmap *bm); + +/** + * Calculate intersection of two bitmaps + * The intersection is defined as all bits that are members of + * both A and B. It's equivalent to bitwise AND. + * This function completes in O(n/sizeof(long)) operations. + * @param a The first bitmaptor + * @param b The second bitmaptor + * @return NULL on errors; A newly created bitmaptor on success. + */ +extern bitmap *bitmap_intersect(const bitmap *a, const bitmap *b); + +/** + * Calculate union of two bitmaps + * The union is defined as all bits that are members of + * A or B or both A and B. It's equivalent to bitwise OR. + * This function completes in O(n/sizeof(long)) operations. + * @param a The first bitmaptor + * @param b The second bitmaptor + * @return NULL on errors; A newly created bitmaptor on success. + */ +extern bitmap *bitmap_union(const bitmap *a, const bitmap *b); + +/** + * Calculate union of two bitmaps and store result in one of them + * @param res The first bitmap + * @param addme The bitmap to unite to the first bitmap + * @return NULL on errors, res on success + */ +extern bitmap *bitmap_unite(bitmap *res, const bitmap *addme); + +/** + * Calculate set difference between two bitmaps + * The set difference of A / B is defined as all members of A + * that isn't members of B. Note that parameter ordering matters + * for this function. + * This function completes in O(n/sizeof(long)) operations. + * @param a The first bitmaptor (numerator) + * @param b The first bitmaptor (denominator) + * @return NULL on errors; A newly created bitmaptor on success. + */ +extern bitmap *bitmap_diff(const bitmap *a, const bitmap *b); + +/** + * Calculate symmetric difference between two bitmaps + * The symmetric difference between A and B is the set that + * contains all elements in either set but not in both. + * This function completes in O(n/sizeof(long)) operations. + * @param a The first bitmaptor + * @param b The second bitmaptor + */ +extern bitmap *bitmap_symdiff(const bitmap *a, const bitmap *b); + +/** + * Compare two bitmaps for equality + * @param a The first bitmaptor + * @param b The other bitmaptor + * @return Similar to memcmp(), with tiebreaks determined by cardinality + */ +extern int bitmap_cmp(const bitmap *a, const bitmap *b); +/** @} */ +#endif /* LIBNAGIOS_bitmap_h__ */ diff --git a/nagios4/broker.h b/nagios4/broker.h new file mode 100644 index 0000000..3c339be --- /dev/null +++ b/nagios4/broker.h @@ -0,0 +1,213 @@ +/***************************************************************************** + * + * BROKER.H - Event broker includes for Nagios + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _BROKER_H +#define _BROKER_H + +#include "nagios.h" + +/*************** EVENT BROKER OPTIONS *****************/ + +#define BROKER_NOTHING 0 +#define BROKER_EVERYTHING 1048575 + +#define BROKER_PROGRAM_STATE 1 /* DONE */ +#define BROKER_TIMED_EVENTS 2 /* DONE */ +#define BROKER_SERVICE_CHECKS 4 /* DONE */ +#define BROKER_HOST_CHECKS 8 /* DONE */ +#define BROKER_EVENT_HANDLERS 16 /* DONE */ +#define BROKER_LOGGED_DATA 32 /* DONE */ +#define BROKER_NOTIFICATIONS 64 /* DONE */ +#define BROKER_FLAPPING_DATA 128 /* DONE */ +#define BROKER_COMMENT_DATA 256 /* DONE */ +#define BROKER_DOWNTIME_DATA 512 /* DONE */ +#define BROKER_SYSTEM_COMMANDS 1024 /* DONE */ +#define BROKER_OCP_DATA_UNUSED 2048 /* reusable */ +#define BROKER_STATUS_DATA 4096 /* DONE */ +#define BROKER_ADAPTIVE_DATA 8192 /* DONE */ +#define BROKER_EXTERNALCOMMAND_DATA 16384 /* DONE */ +#define BROKER_RETENTION_DATA 32768 /* DONE */ +#define BROKER_ACKNOWLEDGEMENT_DATA 65536 +#define BROKER_STATECHANGE_DATA 131072 +#define BROKER_RESERVED18 262144 +#define BROKER_RESERVED19 524288 + + +/****** EVENT TYPES ************************/ + +#define NEBTYPE_NONE 0 + +#define NEBTYPE_HELLO 1 +#define NEBTYPE_GOODBYE 2 +#define NEBTYPE_INFO 3 + +#define NEBTYPE_PROCESS_START 100 +#define NEBTYPE_PROCESS_DAEMONIZE 101 +#define NEBTYPE_PROCESS_RESTART 102 +#define NEBTYPE_PROCESS_SHUTDOWN 103 +#define NEBTYPE_PROCESS_PRELAUNCH 104 /* before objects are read or verified */ +#define NEBTYPE_PROCESS_EVENTLOOPSTART 105 +#define NEBTYPE_PROCESS_EVENTLOOPEND 106 + +#define NEBTYPE_TIMEDEVENT_ADD 200 +#define NEBTYPE_TIMEDEVENT_REMOVE 201 +#define NEBTYPE_TIMEDEVENT_EXECUTE 202 +#define NEBTYPE_TIMEDEVENT_DELAY 203 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SKIP 204 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SLEEP 205 + +#define NEBTYPE_LOG_DATA 300 +#define NEBTYPE_LOG_ROTATION 301 + +#define NEBTYPE_SYSTEM_COMMAND_START 400 +#define NEBTYPE_SYSTEM_COMMAND_END 401 + +#define NEBTYPE_EVENTHANDLER_START 500 +#define NEBTYPE_EVENTHANDLER_END 501 + +#define NEBTYPE_NOTIFICATION_START 600 +#define NEBTYPE_NOTIFICATION_END 601 +#define NEBTYPE_CONTACTNOTIFICATION_START 602 +#define NEBTYPE_CONTACTNOTIFICATION_END 603 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_START 604 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_END 605 + +#define NEBTYPE_SERVICECHECK_INITIATE 700 +#define NEBTYPE_SERVICECHECK_PROCESSED 701 +#define NEBTYPE_SERVICECHECK_RAW_START 702 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_RAW_END 703 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_ASYNC_PRECHECK 704 + +#define NEBTYPE_HOSTCHECK_INITIATE 800 /* a check of the route to the host has been initiated */ +#define NEBTYPE_HOSTCHECK_PROCESSED 801 /* the processed/final result of a host check */ +#define NEBTYPE_HOSTCHECK_RAW_START 802 /* the start of a "raw" host check */ +#define NEBTYPE_HOSTCHECK_RAW_END 803 /* a finished "raw" host check */ +#define NEBTYPE_HOSTCHECK_ASYNC_PRECHECK 804 +#define NEBTYPE_HOSTCHECK_SYNC_PRECHECK 805 + +#define NEBTYPE_COMMENT_ADD 900 +#define NEBTYPE_COMMENT_DELETE 901 +#define NEBTYPE_COMMENT_LOAD 902 + +#define NEBTYPE_FLAPPING_START 1000 +#define NEBTYPE_FLAPPING_STOP 1001 + +#define NEBTYPE_DOWNTIME_ADD 1100 +#define NEBTYPE_DOWNTIME_DELETE 1101 +#define NEBTYPE_DOWNTIME_LOAD 1102 +#define NEBTYPE_DOWNTIME_START 1103 +#define NEBTYPE_DOWNTIME_STOP 1104 + +#define NEBTYPE_PROGRAMSTATUS_UPDATE 1200 +#define NEBTYPE_HOSTSTATUS_UPDATE 1201 +#define NEBTYPE_SERVICESTATUS_UPDATE 1202 +#define NEBTYPE_CONTACTSTATUS_UPDATE 1203 + +#define NEBTYPE_ADAPTIVEPROGRAM_UPDATE 1300 +#define NEBTYPE_ADAPTIVEHOST_UPDATE 1301 +#define NEBTYPE_ADAPTIVESERVICE_UPDATE 1302 +#define NEBTYPE_ADAPTIVECONTACT_UPDATE 1303 + +#define NEBTYPE_EXTERNALCOMMAND_START 1400 +#define NEBTYPE_EXTERNALCOMMAND_END 1401 + +#define NEBTYPE_AGGREGATEDSTATUS_STARTDUMP 1500 +#define NEBTYPE_AGGREGATEDSTATUS_ENDDUMP 1501 + +#define NEBTYPE_RETENTIONDATA_STARTLOAD 1600 +#define NEBTYPE_RETENTIONDATA_ENDLOAD 1601 +#define NEBTYPE_RETENTIONDATA_STARTSAVE 1602 +#define NEBTYPE_RETENTIONDATA_ENDSAVE 1603 + +#define NEBTYPE_ACKNOWLEDGEMENT_ADD 1700 +#define NEBTYPE_ACKNOWLEDGEMENT_REMOVE 1701 /* NOT IMPLEMENTED */ +#define NEBTYPE_ACKNOWLEDGEMENT_LOAD 1702 /* NOT IMPLEMENTED */ + +#define NEBTYPE_STATECHANGE_START 1800 /* NOT IMPLEMENTED */ +#define NEBTYPE_STATECHANGE_END 1801 + + + +/****** EVENT FLAGS ************************/ + +#define NEBFLAG_NONE 0 +#define NEBFLAG_PROCESS_INITIATED 1 /* event was initiated by Nagios process */ +#define NEBFLAG_USER_INITIATED 2 /* event was initiated by a user request */ +#define NEBFLAG_MODULE_INITIATED 3 /* event was initiated by an event broker module */ + + + + +/****** EVENT ATTRIBUTES *******************/ + +#define NEBATTR_NONE 0 + +#define NEBATTR_SHUTDOWN_NORMAL 1 +#define NEBATTR_SHUTDOWN_ABNORMAL 2 +#define NEBATTR_RESTART_NORMAL 4 +#define NEBATTR_RESTART_ABNORMAL 8 + +#define NEBATTR_FLAPPING_STOP_NORMAL 1 +#define NEBATTR_FLAPPING_STOP_DISABLED 2 /* flapping stopped because flap detection was disabled */ + +#define NEBATTR_DOWNTIME_STOP_NORMAL 1 +#define NEBATTR_DOWNTIME_STOP_CANCELLED 2 + + + +/****** EVENT BROKER FUNCTIONS *************/ + +#ifdef USE_EVENT_BROKER +NAGIOS_BEGIN_DECL + +struct timeval get_broker_timestamp(struct timeval *); +void broker_program_state(int, int, int, struct timeval *); +void broker_timed_event(int, int, int, timed_event *, struct timeval *); +void broker_log_data(int, int, int, char *, unsigned long, time_t, struct timeval *); +int broker_event_handler(int, int, int, int, void *, int, int, struct timeval, struct timeval, double, int, int, int, char *, char *, char *, struct timeval *); +void broker_system_command(int, int, int, struct timeval, struct timeval, double, int, int, int, char *, char *, struct timeval *); +int broker_host_check(int, int, int, host *, int, int, int, struct timeval, struct timeval, char *, double, double, int, int, int, char *, char *, char *, char *, struct timeval *, check_result *); +int broker_service_check(int, int, int, service *, int, struct timeval, struct timeval, char *, double, double, int, int, int, char *, struct timeval *, check_result *); +void broker_comment_data(int, int, int, int, int, char *, char *, time_t, char *, char *, int, int, int, time_t, unsigned long, struct timeval *); +void broker_downtime_data(int, int, int, int, char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long, struct timeval *); +void broker_flapping_data(int, int, int, int, void *, double, double, double, struct timeval *); +void broker_program_status(int, int, int, struct timeval *); +void broker_host_status(int, int, int, host *, struct timeval *); +void broker_service_status(int, int, int, service *, struct timeval *); +void broker_contact_status(int, int, int, contact *, struct timeval *); +int broker_notification_data(int, int, int, int, int, struct timeval, struct timeval, void *, char *, char *, int, int, struct timeval *); +int broker_contact_notification_data(int, int, int, int, int, struct timeval, struct timeval, void *, contact *, char *, char *, int, struct timeval *); +int broker_contact_notification_method_data(int, int, int, int, int, struct timeval, struct timeval, void *, contact *, char *, char *, char *, int, struct timeval *); +void broker_adaptive_program_data(int, int, int, int, unsigned long, unsigned long, unsigned long, unsigned long, struct timeval *); +void broker_adaptive_host_data(int, int, int, host *, int, unsigned long, unsigned long, struct timeval *); +void broker_adaptive_service_data(int, int, int, service *, int, unsigned long, unsigned long, struct timeval *); +void broker_adaptive_contact_data(int, int, int, contact *, int, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, struct timeval *); +void broker_external_command(int, int, int, int, time_t, char *, char *, struct timeval *); +void broker_aggregated_status_data(int, int, int, struct timeval *); +void broker_retention_data(int, int, int, struct timeval *); +void broker_acknowledgement_data(int, int, int, int, void *, char *, char *, int, int, int, struct timeval *); +void broker_statechange_data(int, int, int, int, void *, int, int, int, int, struct timeval *); + +NAGIOS_END_DECL +#endif + +#endif diff --git a/nagios4/cgiauth.h b/nagios4/cgiauth.h new file mode 100644 index 0000000..cb96656 --- /dev/null +++ b/nagios4/cgiauth.h @@ -0,0 +1,70 @@ +/***************************************************************************** + * + * CGIAUTH.H - Authorization utilities header file + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _AUTH_H +#define _AUTH_H +#include "common.h" +#include "objects.h" + +NAGIOS_BEGIN_DECL + +typedef struct authdata_struct { + char *username; + int authorized_for_all_hosts; + int authorized_for_all_host_commands; + int authorized_for_all_services; + int authorized_for_all_service_commands; + int authorized_for_system_information; + int authorized_for_system_commands; + int authorized_for_configuration_information; + int authorized_for_read_only; + int authenticated; + } authdata; + + + +int get_authentication_information(authdata *); /* gets current authentication information */ + +int is_authorized_for_host(host *, authdata *); +int is_authorized_for_service(service *, authdata *); + +int is_authorized_for_all_hosts(authdata *); +int is_authorized_for_all_services(authdata *); + +int is_authorized_for_system_information(authdata *); +int is_authorized_for_system_commands(authdata *); +int is_authorized_for_host_commands(host *, authdata *); +int is_authorized_for_service_commands(service *, authdata *); + +int is_authorized_for_hostgroup(hostgroup *, authdata *); +int is_authorized_for_servicegroup(servicegroup *, authdata *); + +int is_authorized_for_hostgroup_commands(hostgroup *, authdata *); +int is_authorized_for_servicegroup_commands(servicegroup *, authdata *); + +int is_authorized_for_configuration_information(authdata *); + +int is_authorized_for_read_only(authdata *); + +NAGIOS_END_DECL + +#endif diff --git a/nagios4/cgiutils.h b/nagios4/cgiutils.h new file mode 100644 index 0000000..6bfbe9b --- /dev/null +++ b/nagios4/cgiutils.h @@ -0,0 +1,479 @@ +/************************************************************************ + * + * CGIUTILS.H - Header file for common CGI functions + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _CGIUTILS_H +#define _CGIUTILS_H +#include "lib/libnagios.h" +#include "logging.h" +#include "objects.h" +#include "cgiauth.h" + +NAGIOS_BEGIN_DECL + + /**************************** CGI REFRESH RATE ******************************/ + +#define DEFAULT_REFRESH_RATE 60 /* 60 second refresh rate for CGIs */ + + + /******************************* CGI NAMES **********************************/ + +#define STATUS_CGI "status.cgi" +#define STATUSMAP_CGI "statusmap.cgi" +#define STATUSWORLD_CGI "statuswrl.cgi" +#define COMMAND_CGI "cmd.cgi" +#define EXTINFO_CGI "extinfo.cgi" +#define SHOWLOG_CGI "showlog.cgi" +#define NOTIFICATIONS_CGI "notifications.cgi" +#define HISTORY_CGI "history.cgi" +#define CONFIG_CGI "config.cgi" +#define OUTAGES_CGI "outages.cgi" +#define TRENDS_CGI "trends.cgi" +#define AVAIL_CGI "avail.cgi" +#define TAC_CGI "tac.cgi" +#define STATUSWML_CGI "statuswml.cgi" +#define TRACEROUTE_CGI "traceroute.cgi" +#define HISTOGRAM_CGI "histogram.cgi" +#define CHECKSANITY_CGI "checksanity.cgi" +#define MINISTATUS_CGI "ministatus.cgi" +#define SUMMARY_CGI "summary.cgi" + + + /**************************** STYLE SHEET NAMES ******************************/ + +#define COMMON_CSS "common.css" + +#define SHOWLOG_CSS "showlog.css" +#define STATUS_CSS "status.css" +#define STATUSMAP_CSS "statusmap.css" +#define COMMAND_CSS "cmd.css" +#define EXTINFO_CSS "extinfo.css" +#define NOTIFICATIONS_CSS "notifications.css" +#define HISTORY_CSS "history.css" +#define CONFIG_CSS "config.css" +#define OUTAGES_CSS "outages.css" +#define TRENDS_CSS "trends.css" +#define AVAIL_CSS "avail.css" +#define TAC_CSS "tac.css" +#define HISTOGRAM_CSS "histogram.css" +#define CHECKSANITY_CSS "checksanity.css" +#define MINISTATUS_CSS "ministatus.css" +#define SUMMARY_CSS "summary.css" + + /********************************* JAVASCRIPT INCLUDES **********************/ +#define JQUERY_JS "jquery-1.7.1.min.js" + + /********************************* ICONS ************************************/ + +#define STATUS_ICON_WIDTH 20 +#define STATUS_ICON_HEIGHT 20 + +#define INFO_ICON "info.png" +#define INFO_ICON_ALT "Informational Message" +#define START_ICON "start.gif" +#define START_ICON_ALT "Program Start" +#define STOP_ICON "stop.gif" +#define STOP_ICON_ALT "Program End" +#define RESTART_ICON "restart.gif" +#define RESTART_ICON_ALT "Program Restart" +#define OK_ICON "recovery.png" +#define OK_ICON_ALT "Service Ok" +#define CRITICAL_ICON "critical.png" +#define CRITICAL_ICON_ALT "Service Critical" +#define WARNING_ICON "warning.png" +#define WARNING_ICON_ALT "Service Warning" +#define UNKNOWN_ICON "unknown.png" +#define UNKNOWN_ICON_ALT "Service Unknown" +#define NOTIFICATION_ICON "notify.gif" +#define NOTIFICATION_ICON_ALT "Service Notification" +#define LOG_ROTATION_ICON "logrotate.png" +#define LOG_ROTATION_ICON_ALT "Log Rotation" +#define EXTERNAL_COMMAND_ICON "command.png" +#define EXTERNAL_COMMAND_ICON_ALT "External Command" + +#define STATUS_DETAIL_ICON "status2.gif" +#define STATUS_OVERVIEW_ICON "status.gif" +#define STATUSMAP_ICON "status3.gif" +#define STATUSWORLD_ICON "status4.gif" +#define EXTINFO_ICON "extinfo.gif" +#define HISTORY_ICON "history.gif" +#define CONTACTGROUP_ICON "contactgroup.gif" +#define TRENDS_ICON "trends.gif" + +#define DISABLED_ICON "disabled.gif" +#define ENABLED_ICON "enabled.gif" +#define PASSIVE_ONLY_ICON "passiveonly.gif" +#define NOTIFICATIONS_DISABLED_ICON "ndisabled.gif" +#define ACKNOWLEDGEMENT_ICON "ack.gif" +#define REMOVE_ACKNOWLEDGEMENT_ICON "noack.gif" +#define COMMENT_ICON "comment.gif" +#define DELETE_ICON "delete.gif" +#define DELAY_ICON "delay.gif" +#define DOWNTIME_ICON "downtime.gif" +#define PASSIVE_ICON "passiveonly.gif" +#define RIGHT_ARROW_ICON "right.gif" +#define LEFT_ARROW_ICON "left.gif" +#define UP_ARROW_ICON "up.gif" +#define DOWN_ARROW_ICON "down.gif" +#define FLAPPING_ICON "flapping.gif" +#define SCHEDULED_DOWNTIME_ICON "downtime.gif" +#define EMPTY_ICON "empty.gif" + +#define ACTIVE_ICON "active.gif" +#define ACTIVE_ICON_ALT "Active Mode" +#define STANDBY_ICON "standby.gif" +#define STANDBY_ICON_ALT "Standby Mode" + +#define HOST_DOWN_ICON "critical.png" +#define HOST_DOWN_ICON_ALT "Host Down" +#define HOST_UNREACHABLE_ICON "critical.png" +#define HOST_UNREACHABLE_ICON_ALT "Host Unreachable" +#define HOST_UP_ICON "recovery.png" +#define HOST_UP_ICON_ALT "Host Up" +#define HOST_NOTIFICATION_ICON "notify.gif" +#define HOST_NOTIFICATION_ICON_ALT "Host Notification" + +#define SERVICE_EVENT_ICON "serviceevent.gif" +#define SERVICE_EVENT_ICON_ALT "Service Event Handler" +#define HOST_EVENT_ICON "hostevent.gif" +#define HOST_EVENT_ICON_ALT "Host Event Handler" + +#define THERM_OK_IMAGE "thermok.png" +#define THERM_WARNING_IMAGE "thermwarn.png" +#define THERM_CRITICAL_IMAGE "thermcrit.png" + +#define CONFIGURATION_ICON "config.gif" +#define NOTES_ICON "notes.gif" +#define ACTION_ICON "action.gif" +#define DETAIL_ICON "detail.gif" + +#define PARENT_TRAVERSAL_ICON "parentup.gif" + +#define TAC_DISABLED_ICON "tacdisabled.png" +#define TAC_ENABLED_ICON "tacenabled.png" + +#define ZOOM1_ICON "zoom1.gif" +#define ZOOM2_ICON "zoom2.gif" + +#define CONTEXT_HELP_ICON1 "contexthelp1.gif" +#define CONTEXT_HELP_ICON2 "contexthelp2.gif" + +#define SPLUNK_SMALL_WHITE_ICON "splunk1.gif" +#define SPLUNK_SMALL_BLACK_ICON "splunk2.gif" + +#define FIRST_PAGE_ICON "b_first2.png" +#define LAST_PAGE_ICON "b_last2.png" +#define NEXT_PAGE_ICON "b_next2.png" +#define PREVIOUS_PAGE_ICON "b_prev2.png" + + + /********************* EXTENDED INFO CGI DISPLAY TYPES *********************/ + +#define DISPLAY_PROCESS_INFO 0 +#define DISPLAY_HOST_INFO 1 +#define DISPLAY_SERVICE_INFO 2 +#define DISPLAY_COMMENTS 3 +#define DISPLAY_PERFORMANCE 4 +#define DISPLAY_HOSTGROUP_INFO 5 +#define DISPLAY_DOWNTIME 6 +#define DISPLAY_SCHEDULING_QUEUE 7 +#define DISPLAY_SERVICEGROUP_INFO 8 + + + /************************ COMMAND CGI COMMAND MODES *************************/ + +#define CMDMODE_NONE 0 +#define CMDMODE_REQUEST 1 +#define CMDMODE_COMMIT 2 + + + + /******************** HOST AND SERVICE NOTIFICATION TYPES ******************/ + +#define NOTIFICATION_ALL 0 /* all service and host notifications */ +#define NOTIFICATION_SERVICE_ALL 1 /* all types of service notifications */ +#define NOTIFICATION_HOST_ALL 2 /* all types of host notifications */ +#define NOTIFICATION_SERVICE_WARNING 4 +#define NOTIFICATION_SERVICE_UNKNOWN 8 +#define NOTIFICATION_SERVICE_CRITICAL 16 +#define NOTIFICATION_SERVICE_RECOVERY 32 +#define NOTIFICATION_HOST_DOWN 64 +#define NOTIFICATION_HOST_UNREACHABLE 128 +#define NOTIFICATION_HOST_RECOVERY 256 +#define NOTIFICATION_SERVICE_ACK 512 +#define NOTIFICATION_HOST_ACK 1024 +#define NOTIFICATION_SERVICE_FLAP 2048 +#define NOTIFICATION_HOST_FLAP 4096 +#define NOTIFICATION_SERVICE_CUSTOM 8192 +#define NOTIFICATION_HOST_CUSTOM 16384 + + + /********************** HOST AND SERVICE ALERT TYPES **********************/ + +#define HISTORY_ALL 0 /* all service and host alert */ +#define HISTORY_SERVICE_ALL 1 /* all types of service alerts */ +#define HISTORY_HOST_ALL 2 /* all types of host alerts */ +#define HISTORY_SERVICE_WARNING 4 +#define HISTORY_SERVICE_UNKNOWN 8 +#define HISTORY_SERVICE_CRITICAL 16 +#define HISTORY_SERVICE_RECOVERY 32 +#define HISTORY_HOST_DOWN 64 +#define HISTORY_HOST_UNREACHABLE 128 +#define HISTORY_HOST_RECOVERY 256 + + + /****************************** SORT TYPES *******************************/ + +#define SORT_NONE 0 +#define SORT_ASCENDING 1 +#define SORT_DESCENDING 2 + + + /***************************** SORT OPTIONS ******************************/ + +#define SORT_NOTHING 0 +#define SORT_HOSTNAME 1 +#define SORT_SERVICENAME 2 +#define SORT_SERVICESTATUS 3 +#define SORT_LASTCHECKTIME 4 +#define SORT_CURRENTATTEMPT 5 +#define SORT_STATEDURATION 6 +#define SORT_NEXTCHECKTIME 7 +#define SORT_HOSTSTATUS 8 +#define SORT_HOSTURGENCY 9 + + + /****************** HOST AND SERVICE FILTER PROPERTIES *******************/ + +#define HOST_SCHEDULED_DOWNTIME 1 +#define HOST_NO_SCHEDULED_DOWNTIME 2 +#define HOST_STATE_ACKNOWLEDGED 4 +#define HOST_STATE_UNACKNOWLEDGED 8 +#define HOST_CHECKS_DISABLED 16 +#define HOST_CHECKS_ENABLED 32 +#define HOST_EVENT_HANDLER_DISABLED 64 +#define HOST_EVENT_HANDLER_ENABLED 128 +#define HOST_FLAP_DETECTION_DISABLED 256 +#define HOST_FLAP_DETECTION_ENABLED 512 +#define HOST_IS_FLAPPING 1024 +#define HOST_IS_NOT_FLAPPING 2048 +#define HOST_NOTIFICATIONS_DISABLED 4096 +#define HOST_NOTIFICATIONS_ENABLED 8192 +#define HOST_PASSIVE_CHECKS_DISABLED 16384 +#define HOST_PASSIVE_CHECKS_ENABLED 32768 +#define HOST_PASSIVE_CHECK 65536 +#define HOST_ACTIVE_CHECK 131072 +#define HOST_HARD_STATE 262144 +#define HOST_SOFT_STATE 524288 + + +#define SERVICE_SCHEDULED_DOWNTIME 1 +#define SERVICE_NO_SCHEDULED_DOWNTIME 2 +#define SERVICE_STATE_ACKNOWLEDGED 4 +#define SERVICE_STATE_UNACKNOWLEDGED 8 +#define SERVICE_CHECKS_DISABLED 16 +#define SERVICE_CHECKS_ENABLED 32 +#define SERVICE_EVENT_HANDLER_DISABLED 64 +#define SERVICE_EVENT_HANDLER_ENABLED 128 +#define SERVICE_FLAP_DETECTION_ENABLED 256 +#define SERVICE_FLAP_DETECTION_DISABLED 512 +#define SERVICE_IS_FLAPPING 1024 +#define SERVICE_IS_NOT_FLAPPING 2048 +#define SERVICE_NOTIFICATIONS_DISABLED 4096 +#define SERVICE_NOTIFICATIONS_ENABLED 8192 +#define SERVICE_PASSIVE_CHECKS_DISABLED 16384 +#define SERVICE_PASSIVE_CHECKS_ENABLED 32768 +#define SERVICE_PASSIVE_CHECK 65536 +#define SERVICE_ACTIVE_CHECK 131072 +#define SERVICE_HARD_STATE 262144 +#define SERVICE_SOFT_STATE 524288 + + + /****************************** SSI TYPES ********************************/ + +#define SSI_HEADER 0 +#define SSI_FOOTER 1 + + + + /************************ CONTEXT-SENSITIVE HELP *************************/ + +#define CONTEXTHELP_STATUS_DETAIL "A1" +#define CONTEXTHELP_STATUS_HGOVERVIEW "A2" +#define CONTEXTHELP_STATUS_HGSUMMARY "A3" +#define CONTEXTHELP_STATUS_HGGRID "A4" +#define CONTEXTHELP_STATUS_SVCPROBLEMS "A5" +#define CONTEXTHELP_STATUS_HOST_DETAIL "A6" +#define CONTEXTHELP_STATUS_HOSTPROBLEMS "A7" +#define CONTEXTHELP_STATUS_SGOVERVIEW "A8" +#define CONTEXTHELP_STATUS_SGSUMMARY "A9" +#define CONTEXTHELP_STATUS_SGGRID "A10" + +#define CONTEXTHELP_TAC "B1" + +#define CONTEXTHELP_MAP "C1" + +#define CONTEXTHELP_LOG "D1" + +#define CONTEXTHELP_HISTORY "E1" + +#define CONTEXTHELP_NOTIFICATIONS "F1" + +#define CONTEXTHELP_TRENDS_MENU1 "G1" +#define CONTEXTHELP_TRENDS_MENU2 "G2" +#define CONTEXTHELP_TRENDS_MENU3 "G3" +#define CONTEXTHELP_TRENDS_MENU4 "G4" +#define CONTEXTHELP_TRENDS_HOST "G5" +#define CONTEXTHELP_TRENDS_SERVICE "G6" + +#define CONTEXTHELP_AVAIL_MENU1 "H1" +#define CONTEXTHELP_AVAIL_MENU2 "H2" +#define CONTEXTHELP_AVAIL_MENU3 "H3" +#define CONTEXTHELP_AVAIL_MENU4 "H4" +#define CONTEXTHELP_AVAIL_MENU5 "H5" +#define CONTEXTHELP_AVAIL_HOSTGROUP "H6" +#define CONTEXTHELP_AVAIL_HOST "H7" +#define CONTEXTHELP_AVAIL_SERVICE "H8" +#define CONTEXTHELP_AVAIL_SERVICEGROUP "H9" + +#define CONTEXTHELP_EXT_HOST "I1" +#define CONTEXTHELP_EXT_SERVICE "I2" +#define CONTEXTHELP_EXT_HOSTGROUP "I3" +#define CONTEXTHELP_EXT_PROCESS "I4" +#define CONTEXTHELP_EXT_PERFORMANCE "I5" +#define CONTEXTHELP_EXT_COMMENTS "I6" +#define CONTEXTHELP_EXT_DOWNTIME "I7" +#define CONTEXTHELP_EXT_QUEUE "I8" +#define CONTEXTHELP_EXT_SERVICEGROUP "I9" + +#define CONTEXTHELP_CMD_INPUT "J1" +#define CONTEXTHELP_CMD_COMMIT "J2" + +#define CONTEXTHELP_OUTAGES "K1" + +#define CONTEXTHELP_CONFIG_MENU "L1" +#define CONTEXTHELP_CONFIG_HOSTS "L2" +#define CONTEXTHELP_CONFIG_HOSTDEPENDENCIES "L3" +#define CONTEXTHELP_CONFIG_HOSTESCALATIONS "L4" +#define CONTEXTHELP_CONFIG_HOSTGROUPS "L5" +#define CONTEXTHELP_CONFIG_HOSTGROUPESCALATIONS "L6" +#define CONTEXTHELP_CONFIG_SERVICES "L7" +#define CONTEXTHELP_CONFIG_SERVICEDEPENDENCIES "L8" +#define CONTEXTHELP_CONFIG_SERVICEESCALATIONS "L9" +#define CONTEXTHELP_CONFIG_CONTACTS "L10" +#define CONTEXTHELP_CONFIG_CONTACTGROUPS "L11" +#define CONTEXTHELP_CONFIG_TIMEPERIODS "L12" +#define CONTEXTHELP_CONFIG_COMMANDS "L13" +#define CONTEXTHELP_CONFIG_HOSTEXTINFO "L14" +#define CONTEXTHELP_CONFIG_SERVICEEXTINFO "L15" +#define CONTEXTHELP_CONFIG_SERVICEGROUPS "L16" + +#define CONTEXTHELP_HISTOGRAM_MENU1 "M1" +#define CONTEXTHELP_HISTOGRAM_MENU2 "M2" +#define CONTEXTHELP_HISTOGRAM_MENU3 "M3" +#define CONTEXTHELP_HISTOGRAM_MENU4 "M4" +#define CONTEXTHELP_HISTOGRAM_HOST "M5" +#define CONTEXTHELP_HISTOGRAM_SERVICE "M6" + +#define CONTEXTHELP_SUMMARY_MENU "N1" +#define CONTEXTHELP_SUMMARY_RECENT_ALERTS "N2" +#define CONTEXTHELP_SUMMARY_ALERT_TOTALS "N3" +#define CONTEXTHELP_SUMMARY_HOSTGROUP_ALERT_TOTALS "N4" +#define CONTEXTHELP_SUMMARY_HOST_ALERT_TOTALS "N5" +#define CONTEXTHELP_SUMMARY_SERVICE_ALERT_TOTALS "N6" +#define CONTEXTHELP_SUMMARY_ALERT_PRODUCERS "N7" +#define CONTEXTHELP_SUMMARY_SERVICEGROUP_ALERT_TOTALS "N8" + + + /************************** LIFO RETURN CODES ****************************/ + +#define LIFO_OK 0 +#define LIFO_ERROR_MEMORY 1 +#define LIFO_ERROR_FILE 2 +#define LIFO_ERROR_DATA 3 + + + + + +/*************************** DATA STRUCTURES *****************************/ + +/* LIFO data structure */ +typedef struct lifo_struct { + char *data; + struct lifo_struct *next; + } lifo; + +/******************************** FUNCTIONS *******************************/ + +void reset_cgi_vars(void); +void cgi_init(void (*doc_header)(int), void (*doc_footer)(void), int object_options, int status_options); +void free_memory(void); + +const char *get_cgi_config_location(void); /* gets location of the CGI config file to read */ +const char *get_cmd_file_location(void); /* gets location of external command file to write to */ + +int read_cgi_config_file(const char *); +int read_main_config_file(const char *); +int read_all_object_configuration_data(const char *, int); +int read_all_status_data(const char *, int); + +char *unescape_newlines(char *); +void sanitize_plugin_output(char *); /* strips HTML and bad characters from plugin output */ +void strip_html_brackets(char *); /* strips > and < from string */ + +void get_time_string(time_t *, char *, int, int); /* gets a date/time string */ +void get_interval_time_string(double, char *, int); /* gets a time string for an interval of time */ + +const char *url_encode(const char *); /* encodes a string in proper URL format */ +char *html_encode(char *, int); /* encodes a string in HTML format (for what the user sees) */ +char *escape_string(const char *); /* escape string for html form usage */ + +void get_log_archive_to_use(int, char *, int); /* determines the name of the log archive to use */ +void determine_log_rotation_times(int); +int determine_archive_to_use_from_time(time_t); + +void print_extra_hostgroup_url(char *, char *); +void print_extra_servicegroup_url(char *, char *); + +void display_info_table(const char *, int, authdata *); +void display_nav_table(char *, int); + +void display_splunk_host_url(host *); +void display_splunk_service_url(service *); +void display_splunk_generic_url(char *, int); +void strip_splunk_query_terms(char *); + +void include_ssi_files(const char *, int); /* include user-defined SSI footers/headers */ +void include_ssi_file(const char *); /* include user-defined SSI footer/header */ + +void cgi_config_file_error(const char *); +void main_config_file_error(const char *); +void object_data_error(void); +void status_data_error(void); + +void display_context_help(const char *); /* displays context-sensitive help window */ + +int read_file_into_lifo(char *); /* LIFO functions */ +void free_lifo_memory(void); +int push_lifo(char *); +char *pop_lifo(void); + +NAGIOS_END_DECL +#endif diff --git a/nagios4/comments.h b/nagios4/comments.h new file mode 100644 index 0000000..cc4f658 --- /dev/null +++ b/nagios4/comments.h @@ -0,0 +1,118 @@ +/***************************************************************************** + * + * COMMENTS.H - Header file for comment functions + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _COMMENTS_H +#define _COMMENTS_H +#include "common.h" +#include "objects.h" + + +/**************************** COMMENT SOURCES ******************************/ + +#define COMMENTSOURCE_INTERNAL 0 +#define COMMENTSOURCE_EXTERNAL 1 + + + +/***************************** COMMENT TYPES *******************************/ + +#define HOST_COMMENT 1 +#define SERVICE_COMMENT 2 + + +/****************************** ENTRY TYPES ********************************/ + +#define USER_COMMENT 1 +#define DOWNTIME_COMMENT 2 +#define FLAPPING_COMMENT 3 +#define ACKNOWLEDGEMENT_COMMENT 4 + + +/*************************** CHAINED HASH LIMITS ***************************/ + +#define COMMENT_HASHSLOTS 1024 + + +/**************************** DATA STRUCTURES ******************************/ + +NAGIOS_BEGIN_DECL + +/* COMMENT structure */ +typedef struct comment { + int comment_type; + int entry_type; + unsigned long comment_id; + int source; + int persistent; + time_t entry_time; + int expires; + time_t expire_time; + char *host_name; + char *service_description; + char *author; + char *comment_data; + struct comment *next; + struct comment *nexthash; + } comment; + +extern struct comment *comment_list; + +#ifndef NSCGI +int initialize_comment_data(void); /* initializes comment data */ +int add_new_comment(int, int, char *, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); /* adds a new host or service comment */ +int add_new_host_comment(int, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); /* adds a new host comment */ +int add_new_service_comment(int, char *, char *, time_t, char *, char *, int, int, int, time_t, unsigned long *); /* adds a new service comment */ +int delete_comment(int, unsigned long); /* deletes a host or service comment */ +int delete_host_comment(unsigned long); /* deletes a host comment */ +int delete_service_comment(unsigned long); /* deletes a service comment */ +int delete_all_comments(int, char *, char *); /* deletes all comments for a particular host or service */ +int delete_all_host_comments(char *); /* deletes all comments for a specific host */ +int delete_host_acknowledgement_comments(struct host *); /* deletes all non-persistent ack comments for a specific host */ +int delete_all_service_comments(char *, char *); /* deletes all comments for a specific service */ +int delete_service_acknowledgement_comments(struct service *); /* deletes all non-persistent ack comments for a specific service */ + +int check_for_expired_comment(unsigned long); /* expires a comment */ +#endif + +struct comment *find_comment(unsigned long, int); /* finds a specific comment */ +struct comment *find_service_comment(unsigned long); /* finds a specific service comment */ +struct comment *find_host_comment(unsigned long); /* finds a specific host comment */ + +struct comment *get_first_comment_by_host(char *); +struct comment *get_next_comment_by_host(char *, struct comment *); + +int number_of_host_comments(char *); /* returns the number of comments associated with a particular host */ +int number_of_service_comments(char *, char *); /* returns the number of comments associated with a particular service */ + +int add_comment(int, int, char *, char *, time_t, char *, char *, unsigned long, int, int, time_t, int); /* adds a comment (host or service) */ +int sort_comments(void); +int add_host_comment(int, char *, time_t, char *, char *, unsigned long, int, int, time_t, int); /* adds a host comment */ +int add_service_comment(int, char *, char *, time_t, char *, char *, unsigned long, int, int, time_t, int); /* adds a service comment */ + +int add_comment_to_hashlist(struct comment *); + +void free_comment_data(void); /* frees memory allocated to the comment list */ + +NAGIOS_BEGIN_DECL + +#endif diff --git a/nagios4/common.h b/nagios4/common.h new file mode 100644 index 0000000..34c4582 --- /dev/null +++ b/nagios4/common.h @@ -0,0 +1,531 @@ +/************************************************************************ + * + * Nagios Common Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef INCLUDE_COMMON_H +#define INCLUDE_COMMON_H + +#include "shared.h" + +#define PROGRAM_VERSION "4.0.2" +#define PROGRAM_MODIFICATION_DATE "11-25-2013" + +NAGIOS_BEGIN_DECL + +/*************************************************************/ +/************** SHARED GLOBAL VARIABLES **********************/ +/*************************************************************/ +extern int date_format; +extern int interval_length; +extern char *illegal_output_chars; +extern char illegal_output_char_map[256]; + +extern int log_rotation_method; +extern int check_external_commands; +/* set this if you're going to add a ton of comments at once */ +extern int defer_comment_sorting; +extern unsigned long next_downtime_id; + +extern char *object_cache_file; +extern char *status_file; + +extern time_t program_start; +extern int nagios_pid; +extern int daemon_mode; + +extern time_t last_log_rotation; + +extern int process_performance_data; +extern int enable_flap_detection; +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; + +extern int enable_timing_point; + +extern char *config_file_dir; + +#ifdef HAVE_TZNAME +#ifdef CYGWIN +extern char *_tzname[2] __declspec(dllimport); +#else +extern char *tzname[2]; +#endif +#endif + + +NAGIOS_END_DECL + + +/* Experimental performance tweaks - use with caution */ +#undef USE_MEMORY_PERFORMANCE_TWEAKS + + +/****************** OBJECT STATES ********************/ +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN 3 +#define STATE_UP 0 +#define STATE_DOWN 1 +#define STATE_UNREACHABLE 2 +/* for legacy reasons */ +#define HOST_UP STATE_UP +#define HOST_DOWN STATE_DOWN +#define HOST_UNREACHABLE STATE_UNREACHABLE + +/***************************** COMMANDS *********************************/ + +#define CMD_NONE 0 + +#define CMD_ADD_HOST_COMMENT 1 +#define CMD_DEL_HOST_COMMENT 2 + +#define CMD_ADD_SVC_COMMENT 3 +#define CMD_DEL_SVC_COMMENT 4 + +#define CMD_ENABLE_SVC_CHECK 5 +#define CMD_DISABLE_SVC_CHECK 6 + +#define CMD_SCHEDULE_SVC_CHECK 7 + +#define CMD_DELAY_SVC_NOTIFICATION 9 + +#define CMD_DELAY_HOST_NOTIFICATION 10 + +#define CMD_DISABLE_NOTIFICATIONS 11 +#define CMD_ENABLE_NOTIFICATIONS 12 + +#define CMD_RESTART_PROCESS 13 +#define CMD_SHUTDOWN_PROCESS 14 + +#define CMD_ENABLE_HOST_SVC_CHECKS 15 +#define CMD_DISABLE_HOST_SVC_CHECKS 16 + +#define CMD_SCHEDULE_HOST_SVC_CHECKS 17 + +#define CMD_DELAY_HOST_SVC_NOTIFICATIONS 19 /* currently unimplemented */ + +#define CMD_DEL_ALL_HOST_COMMENTS 20 +#define CMD_DEL_ALL_SVC_COMMENTS 21 + +#define CMD_ENABLE_SVC_NOTIFICATIONS 22 +#define CMD_DISABLE_SVC_NOTIFICATIONS 23 +#define CMD_ENABLE_HOST_NOTIFICATIONS 24 +#define CMD_DISABLE_HOST_NOTIFICATIONS 25 +#define CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST 26 +#define CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST 27 +#define CMD_ENABLE_HOST_SVC_NOTIFICATIONS 28 +#define CMD_DISABLE_HOST_SVC_NOTIFICATIONS 29 + +#define CMD_PROCESS_SERVICE_CHECK_RESULT 30 + +#define CMD_SAVE_STATE_INFORMATION 31 +#define CMD_READ_STATE_INFORMATION 32 + +#define CMD_ACKNOWLEDGE_HOST_PROBLEM 33 +#define CMD_ACKNOWLEDGE_SVC_PROBLEM 34 + +#define CMD_START_EXECUTING_SVC_CHECKS 35 +#define CMD_STOP_EXECUTING_SVC_CHECKS 36 + +#define CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS 37 +#define CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS 38 + +#define CMD_ENABLE_PASSIVE_SVC_CHECKS 39 +#define CMD_DISABLE_PASSIVE_SVC_CHECKS 40 + +#define CMD_ENABLE_EVENT_HANDLERS 41 +#define CMD_DISABLE_EVENT_HANDLERS 42 + +#define CMD_ENABLE_HOST_EVENT_HANDLER 43 +#define CMD_DISABLE_HOST_EVENT_HANDLER 44 + +#define CMD_ENABLE_SVC_EVENT_HANDLER 45 +#define CMD_DISABLE_SVC_EVENT_HANDLER 46 + +#define CMD_ENABLE_HOST_CHECK 47 +#define CMD_DISABLE_HOST_CHECK 48 + +#define CMD_START_OBSESSING_OVER_SVC_CHECKS 49 +#define CMD_STOP_OBSESSING_OVER_SVC_CHECKS 50 + +#define CMD_REMOVE_HOST_ACKNOWLEDGEMENT 51 +#define CMD_REMOVE_SVC_ACKNOWLEDGEMENT 52 + +#define CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS 53 +#define CMD_SCHEDULE_FORCED_SVC_CHECK 54 + +#define CMD_SCHEDULE_HOST_DOWNTIME 55 +#define CMD_SCHEDULE_SVC_DOWNTIME 56 + +#define CMD_ENABLE_HOST_FLAP_DETECTION 57 +#define CMD_DISABLE_HOST_FLAP_DETECTION 58 + +#define CMD_ENABLE_SVC_FLAP_DETECTION 59 +#define CMD_DISABLE_SVC_FLAP_DETECTION 60 + +#define CMD_ENABLE_FLAP_DETECTION 61 +#define CMD_DISABLE_FLAP_DETECTION 62 + +#define CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS 63 +#define CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS 64 + +#define CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS 65 +#define CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS 66 + +#define CMD_ENABLE_HOSTGROUP_SVC_CHECKS 67 +#define CMD_DISABLE_HOSTGROUP_SVC_CHECKS 68 + +/* commands 69-77 are unimplemented */ +#define CMD_UNIMPLEMENTED_69 69 +#define CMD_UNIMPLEMENTED_70 70 +#define CMD_UNIMPLEMENTED_71 71 +#define CMD_UNIMPLEMENTED_72 72 +#define CMD_UNIMPLEMENTED_73 73 +#define CMD_UNIMPLEMENTED_74 74 +#define CMD_UNIMPLEMENTED_75 75 +#define CMD_UNIMPLEMENTED_76 76 +#define CMD_UNIMPLEMENTED_77 77 + +#define CMD_DEL_HOST_DOWNTIME 78 +#define CMD_DEL_SVC_DOWNTIME 79 + +#define CMD_ENABLE_PERFORMANCE_DATA 82 +#define CMD_DISABLE_PERFORMANCE_DATA 83 + +#define CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME 84 +#define CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME 85 +#define CMD_SCHEDULE_HOST_SVC_DOWNTIME 86 + +/* new commands in Nagios 2.x found below... */ +#define CMD_PROCESS_HOST_CHECK_RESULT 87 + +#define CMD_START_EXECUTING_HOST_CHECKS 88 +#define CMD_STOP_EXECUTING_HOST_CHECKS 89 + +#define CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS 90 +#define CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS 91 + +#define CMD_ENABLE_PASSIVE_HOST_CHECKS 92 +#define CMD_DISABLE_PASSIVE_HOST_CHECKS 93 + +#define CMD_START_OBSESSING_OVER_HOST_CHECKS 94 +#define CMD_STOP_OBSESSING_OVER_HOST_CHECKS 95 + +#define CMD_SCHEDULE_HOST_CHECK 96 +#define CMD_SCHEDULE_FORCED_HOST_CHECK 98 + +#define CMD_START_OBSESSING_OVER_SVC 99 +#define CMD_STOP_OBSESSING_OVER_SVC 100 + +#define CMD_START_OBSESSING_OVER_HOST 101 +#define CMD_STOP_OBSESSING_OVER_HOST 102 + +#define CMD_ENABLE_HOSTGROUP_HOST_CHECKS 103 +#define CMD_DISABLE_HOSTGROUP_HOST_CHECKS 104 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 105 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 106 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 107 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 108 + +#define CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS 109 +#define CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS 110 + +#define CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS 111 +#define CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS 112 + +#define CMD_ENABLE_SERVICEGROUP_SVC_CHECKS 113 +#define CMD_DISABLE_SERVICEGROUP_SVC_CHECKS 114 + +#define CMD_ENABLE_SERVICEGROUP_HOST_CHECKS 115 +#define CMD_DISABLE_SERVICEGROUP_HOST_CHECKS 116 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 117 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 118 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 119 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 120 + +#define CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME 121 +#define CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME 122 + +#define CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER 123 +#define CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER 124 + +#define CMD_CHANGE_HOST_EVENT_HANDLER 125 +#define CMD_CHANGE_SVC_EVENT_HANDLER 126 + +#define CMD_CHANGE_HOST_CHECK_COMMAND 127 +#define CMD_CHANGE_SVC_CHECK_COMMAND 128 + +#define CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL 129 +#define CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL 130 +#define CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL 131 + +#define CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS 132 +#define CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS 133 + +#define CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME 134 + +#define CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS 135 +#define CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS 136 + +#define CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME 137 + +#define CMD_ENABLE_SERVICE_FRESHNESS_CHECKS 138 +#define CMD_DISABLE_SERVICE_FRESHNESS_CHECKS 139 + +#define CMD_ENABLE_HOST_FRESHNESS_CHECKS 140 +#define CMD_DISABLE_HOST_FRESHNESS_CHECKS 141 + +#define CMD_SET_HOST_NOTIFICATION_NUMBER 142 +#define CMD_SET_SVC_NOTIFICATION_NUMBER 143 + +/* new commands in Nagios 3.x found below... */ +#define CMD_CHANGE_HOST_CHECK_TIMEPERIOD 144 +#define CMD_CHANGE_SVC_CHECK_TIMEPERIOD 145 + +#define CMD_PROCESS_FILE 146 + +#define CMD_CHANGE_CUSTOM_HOST_VAR 147 +#define CMD_CHANGE_CUSTOM_SVC_VAR 148 +#define CMD_CHANGE_CUSTOM_CONTACT_VAR 149 + +#define CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS 150 +#define CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS 151 +#define CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS 152 +#define CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS 153 + +#define CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS 154 +#define CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS 155 +#define CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS 156 +#define CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS 157 + +#define CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL 158 + +#define CMD_SEND_CUSTOM_HOST_NOTIFICATION 159 +#define CMD_SEND_CUSTOM_SVC_NOTIFICATION 160 + +#define CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD 161 +#define CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD 162 +#define CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD 163 +#define CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD 164 + +#define CMD_CHANGE_HOST_MODATTR 165 +#define CMD_CHANGE_SVC_MODATTR 166 +#define CMD_CHANGE_CONTACT_MODATTR 167 +#define CMD_CHANGE_CONTACT_MODHATTR 168 +#define CMD_CHANGE_CONTACT_MODSATTR 169 + +#define CMD_DEL_DOWNTIME_BY_HOST_NAME 170 +#define CMD_DEL_DOWNTIME_BY_HOSTGROUP_NAME 171 +#define CMD_DEL_DOWNTIME_BY_START_TIME_COMMENT 172 + +/* custom command introduced in Nagios 3.x */ +#define CMD_CUSTOM_COMMAND 999 + +/**************************** COMMAND ERRORS *****************************/ +#define CMD_ERROR_OK 0 /* No errors encountered */ +#define CMD_ERROR_UNKNOWN_COMMAND 1 /* Unknown/unsupported command */ +#define CMD_ERROR_MALFORMED_COMMAND 2 /* Command malformed/missing timestamp? */ +#define CMD_ERROR_INTERNAL_ERROR 3 /* Internal error */ +#define CMD_ERROR_FAILURE 4 /* Command routine failed */ + +extern const char *cmd_error_strerror(int error_code); + +/**************************** CHECK TYPES ********************************/ + +#define CHECK_TYPE_ACTIVE 0 +#define CHECK_TYPE_PASSIVE 1 +#define CHECK_TYPE_PARENT 2 /* (active) check for the benefit of dependent objects */ +#define CHECK_TYPE_FILE 3 /* from spool files (yuck) */ +#define CHECK_TYPE_OTHER 4 /* for modules to use */ + + +/************* LEGACY (deprecated) CHECK TYPES ***************************/ + +#define SERVICE_CHECK_ACTIVE CHECK_TYPE_ACTIVE +#define SERVICE_CHECK_PASSIVE CHECK_TYPE_PASSIVE +#define HOST_CHECK_ACTIVE CHECK_TYPE_ACTIVE +#define HOST_CHECK_PASSIVE CHECK_TYPE_PASSIVE + + +/************************ SERVICE STATE TYPES ****************************/ + +#define SOFT_STATE 0 +#define HARD_STATE 1 + + +/************************* SCHEDULED DOWNTIME TYPES **********************/ + +#define SERVICE_DOWNTIME 1 /* service downtime */ +#define HOST_DOWNTIME 2 /* host downtime */ +#define ANY_DOWNTIME 3 /* host or service downtime */ + + +/************************** NOTIFICATION OPTIONS *************************/ + +#define NOTIFICATION_OPTION_NONE 0 +#define NOTIFICATION_OPTION_BROADCAST 1 +#define NOTIFICATION_OPTION_FORCED 2 +#define NOTIFICATION_OPTION_INCREMENT 4 + + +/************************** ACKNOWLEDGEMENT TYPES ************************/ + +#define HOST_ACKNOWLEDGEMENT 0 +#define SERVICE_ACKNOWLEDGEMENT 1 + +#define ACKNOWLEDGEMENT_NONE 0 +#define ACKNOWLEDGEMENT_NORMAL 1 +#define ACKNOWLEDGEMENT_STICKY 2 + + +/**************************** DEPENDENCY TYPES ***************************/ + +#define NOTIFICATION_DEPENDENCY 1 +#define EXECUTION_DEPENDENCY 2 + + + +/********************** HOST/SERVICE CHECK OPTIONS ***********************/ + +#define CHECK_OPTION_NONE 0 /* no check options */ +#define CHECK_OPTION_FORCE_EXECUTION 1 /* force execution of a check (ignores disabled services/hosts, invalid timeperiods) */ +#define CHECK_OPTION_FRESHNESS_CHECK 2 /* this is a freshness check */ +#define CHECK_OPTION_ORPHAN_CHECK 4 /* this is an orphan check */ +#define CHECK_OPTION_DEPENDENCY_CHECK 8 /* dependency check. different scheduling rules apply */ + + +/**************************** PROGRAM MODES ******************************/ + +#define STANDBY_MODE 0 +#define ACTIVE_MODE 1 + + +/************************** LOG ROTATION MODES ***************************/ + +#define LOG_ROTATION_NONE 0 +#define LOG_ROTATION_HOURLY 1 +#define LOG_ROTATION_DAILY 2 +#define LOG_ROTATION_WEEKLY 3 +#define LOG_ROTATION_MONTHLY 4 + + +/***************************** LOG VERSIONS ******************************/ + +#define LOG_VERSION_1 "1.0" +#define LOG_VERSION_2 "2.0" + + + +/*************************** CHECK STATISTICS ****************************/ + +#define ACTIVE_SCHEDULED_SERVICE_CHECK_STATS 0 +#define ACTIVE_ONDEMAND_SERVICE_CHECK_STATS 1 +#define PASSIVE_SERVICE_CHECK_STATS 2 +#define ACTIVE_SCHEDULED_HOST_CHECK_STATS 3 +#define ACTIVE_ONDEMAND_HOST_CHECK_STATS 4 +#define PASSIVE_HOST_CHECK_STATS 5 +#define ACTIVE_CACHED_HOST_CHECK_STATS 6 +#define ACTIVE_CACHED_SERVICE_CHECK_STATS 7 +#define EXTERNAL_COMMAND_STATS 8 +#define PARALLEL_HOST_CHECK_STATS 9 +#define SERIAL_HOST_CHECK_STATS 10 +#define MAX_CHECK_STATS_TYPES 11 + + +/****************** HOST CONFIG FILE READING OPTIONS ********************/ + +#define READ_HOSTS 1 +#define READ_HOSTGROUPS 2 +#define READ_CONTACTS 4 +#define READ_CONTACTGROUPS 8 +#define READ_SERVICES 16 +#define READ_COMMANDS 32 +#define READ_TIMEPERIODS 64 +#define READ_SERVICEESCALATIONS 128 +#define READ_HOSTGROUPESCALATIONS 256 /* no longer implemented */ +#define READ_SERVICEDEPENDENCIES 512 +#define READ_HOSTDEPENDENCIES 1024 +#define READ_HOSTESCALATIONS 2048 +#define READ_HOSTEXTINFO 4096 +#define READ_SERVICEEXTINFO 8192 +#define READ_SERVICEGROUPS 16384 + +#define READ_ALL_OBJECT_DATA READ_HOSTS | READ_HOSTGROUPS | READ_CONTACTS | READ_CONTACTGROUPS | READ_SERVICES | READ_COMMANDS | READ_TIMEPERIODS | READ_SERVICEESCALATIONS | READ_SERVICEDEPENDENCIES | READ_HOSTDEPENDENCIES | READ_HOSTESCALATIONS | READ_HOSTEXTINFO | READ_SERVICEEXTINFO | READ_SERVICEGROUPS + + +/************************** DATE/TIME TYPES *****************************/ + +#define LONG_DATE_TIME 0 +#define SHORT_DATE_TIME 1 +#define SHORT_DATE 2 +#define SHORT_TIME 3 +#define HTTP_DATE_TIME 4 /* time formatted for use in HTTP headers */ + + +/**************************** DATE FORMATS ******************************/ + +#define DATE_FORMAT_US 0 /* U.S. (MM-DD-YYYY HH:MM:SS) */ +#define DATE_FORMAT_EURO 1 /* European (DD-MM-YYYY HH:MM:SS) */ +#define DATE_FORMAT_ISO8601 2 /* ISO8601 (YYYY-MM-DD HH:MM:SS) */ +#define DATE_FORMAT_STRICT_ISO8601 3 /* ISO8601 (YYYY-MM-DDTHH:MM:SS) */ + + +/************************** MISC DEFINITIONS ****************************/ + +#define MAX_FILENAME_LENGTH 256 /* max length of path/filename that Nagios will process */ +#define MAX_INPUT_BUFFER 1024 /* size in bytes of max. input buffer (for reading files, misc stuff) */ +#define MAX_COMMAND_BUFFER 8192 /* max length of raw or processed command line */ +#define MAX_EXTERNAL_COMMAND_LENGTH 8192 /* max length of an external command */ + +#define MAX_DATETIME_LENGTH 48 + + +/************************* MODIFIED ATTRIBUTES **************************/ + +#define MODATTR_NONE 0 +#define MODATTR_NOTIFICATIONS_ENABLED 1 +#define MODATTR_ACTIVE_CHECKS_ENABLED 2 +#define MODATTR_PASSIVE_CHECKS_ENABLED 4 +#define MODATTR_EVENT_HANDLER_ENABLED 8 +#define MODATTR_FLAP_DETECTION_ENABLED 16 +#define MODATTR_FAILURE_PREDICTION_ENABLED 32 +#define MODATTR_PERFORMANCE_DATA_ENABLED 64 +#define MODATTR_OBSESSIVE_HANDLER_ENABLED 128 +#define MODATTR_EVENT_HANDLER_COMMAND 256 +#define MODATTR_CHECK_COMMAND 512 +#define MODATTR_NORMAL_CHECK_INTERVAL 1024 +#define MODATTR_RETRY_CHECK_INTERVAL 2048 +#define MODATTR_MAX_CHECK_ATTEMPTS 4096 +#define MODATTR_FRESHNESS_CHECKS_ENABLED 8192 +#define MODATTR_CHECK_TIMEPERIOD 16384 +#define MODATTR_CUSTOM_VARIABLE 32768 +#define MODATTR_NOTIFICATION_TIMEPERIOD 65536 +#endif /* INCLUDE_COMMON_H */ diff --git a/nagios4/config.h b/nagios4/config.h new file mode 100644 index 0000000..a7a25ba --- /dev/null +++ b/nagios4/config.h @@ -0,0 +1,344 @@ +/* include/config.h. Generated from config.h.in by configure. */ +/************************************************************************ + * + * Nagios Config Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + + +/***** NAGIOS STUFF *****/ + +#define DEFAULT_NAGIOS_USER "nagios" +#define DEFAULT_NAGIOS_GROUP "nagios" + +/* stop gcc from bitching about implicit asprintf declarations */ +#define _GNU_SOURCE 1 + +/* Event broker integration */ +#define USE_EVENT_BROKER /**/ + +/* commands used by CGIs */ +#define TRACEROUTE_COMMAND "/usr/sbin/traceroute" +/* #undef PING_COMMAND */ +/* #undef PING_PACKETS_FIRST */ + +/* Debugging options */ +/* function entry and exit */ +/* #undef DEBUG0 */ +/* general info messages */ +/* #undef DEBUG1 */ +/* warning messages */ +/* #undef DEBUG2 */ +/* service and host checks, other events */ +/* #undef DEBUG3 */ +/* service and host notifications */ +/* #undef DEBUG4 */ +/* SQL queries (defunct) */ +/* #undef DEBUG5 */ + +/* I/O implementations */ +/* #undef USE_XSDDEFAULT */ +/* #undef USE_XCDDEFAULT */ +/* #undef USE_XRDDEFAULT */ +/* #undef USE_XODTEMPLATE */ +/* #undef USE_XPDDEFAULT */ +/* #undef USE_XDDDEFAULT */ + + +/***** CGI COMPILE OPTIONS *****/ +/* should we compile and use the statusmap CGI? */ +/* #undef USE_STATUSMAP */ +/* should we compile and use the statuswrl CGI? */ +#define USE_STATUSWRL /**/ +/* should we compile and use the trends CGI? */ +/* #undef USE_TRENDS */ +/* should we compile and use the histogram CGI? */ +/* #undef USE_HISTOGRAM */ + + + +/***** FUNCTION DEFINITIONS *****/ + +#define HAVE_SETENV 1 +#define HAVE_UNSETENV 1 +/* #undef HAVE_SOCKET */ +#define HAVE_STRDUP 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOUL 1 +#define HAVE_INITGROUPS 1 +/* #undef HAVE_GETLOADAVG */ +/* #undef HAVE_GDIMAGECREATETRUECOLOR */ + + + +/***** ASPRINTF() AND FRIENDS *****/ + +/* #undef HAVE_VSNPRINTF */ +/* #undef HAVE_SNPRINTF */ +/* #undef HAVE_ASPRINTF */ +/* #undef HAVE_VASPRINTF */ +#define HAVE_C99_VSNPRINTF 1 +#define HAVE_VA_COPY 1 +/* #undef HAVE___VA_COPY */ + + + +/***** MISC DEFINITIONS *****/ + +#define USE_NANOSLEEP /**/ +#define STDC_HEADERS 1 +#define HAVE_TM_ZONE 1 +/* #undef HAVE_TZNAME */ +/* #undef USE_PROC */ +#define SOCKET_SIZE_TYPE size_t +#define GETGROUPS_T gid_t +#define RETSIGTYPE void + + + +/***** HEADER FILES *****/ + +#include +#include + +/* needed for the time_t structures we use later... */ +/* this include must come before sys/resource.h or we can have problems on some OSes */ +#define TIME_WITH_SYS_TIME 1 +#define HAVE_SYS_TIME_H 1 +#if TIME_WITH_SYS_TIME +#include +#include +#else +#if HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + +#define HAVE_SYS_RESOURCE_H 1 +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +#define HAVE_LIMITS_H 1 +#ifdef HAVE_LIMITS_H +#include +#endif + +#define HAVE_PWD_H 1 +#ifdef HAVE_PWD_H +#include +#endif + +#define HAVE_GRP_H 1 +#ifdef HAVE_GRP_H +#include +#endif + +#define HAVE_STRINGS_H 1 +#ifdef HAVE_STRINGS_H +#include +#endif + +#define HAVE_STRING_H 1 +#ifdef HAVE_STRINGS_H +#include +#endif + +#define HAVE_UNISTD_H 1 +#ifdef HAVE_UNISTD_H +#include +#endif + +#define HAVE_SYSLOG_H 1 +#ifdef HAVE_SYSLOG_H +#include +#endif + +#define HAVE_SIGNAL_H 1 +#ifdef HAVE_SIGNAL_H +#include +#endif + +#define HAVE_SYS_STAT_H 1 +#ifdef HAVE_SYS_STAT_H +#include +#endif + +#define HAVE_SYS_MMAN_H 1 +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +#define HAVE_FCNTL_H 1 +#ifdef HAVE_FCNTL_H +#include +#endif + +#define HAVE_STDARG_H 1 +#ifdef HAVE_STDARG_H +#include +#endif + +#define HAVE_SYS_TYPES_H 1 +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#define HAVE_SYS_WAIT_H 1 +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#define HAVE_ERRNO_H 1 +#ifdef HAVE_ERRNO_H +#include +#endif + +#define HAVE_SYS_TIMEB_H 1 +#if HAVE_SYS_TIMEB_H +#include +#endif + +#define HAVE_SYS_IPC_H 1 +#ifdef HAVE_SYS_IPC_H +#include +#endif + +#define HAVE_SYS_MSG_H 1 +#ifdef HAVE_SYS_MSG_H +#include +#endif + +#define HAVE_MATH_H 1 +#ifdef HAVE_MATH_H +#include +#endif + +#define HAVE_CTYPE_H 1 +#ifdef HAVE_CTYPE_H +#include +#endif + +#define HAVE_DIRENT_H 1 +#ifdef HAVE_DIRENT_H +#include +#endif + +#define HAVE_REGEX_H 1 +#ifdef HAVE_REGEX_H +#include + +#define HAVE_SYS_SOCKET_H 1 +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +/* #undef HAVE_SOCKET */ +#ifdef HAVE_SOCKET_H +#include +#endif + +#define HAVE_NETINET_IN_H 1 +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#define HAVE_ARPA_INET_H 1 +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#define HAVE_NETDB_H 1 +#ifdef HAVE_NETDB_H +#include +#endif + +#define HAVE_LIBGEN_H 1 +#ifdef HAVE_LIBGEN_H +#include +#endif + +#define HAVE_SYS_UN_H 1 +#ifdef HAVE_SYS_UN_H +#include +#endif + +#define HAVE_SYS_POLL_H 1 +#ifdef HAVE_SYS_POLL_H +#include +#endif + +#define HAVE_GETOPT_H 1 +#ifdef HAVE_GETOPT_H +#include +#endif + +/* #undef HAVE_LINUX_MODULE_H */ +#ifdef HAVE_LINUX_MODULE_H +#include +#endif + +#define HAVE_LOCALE_H 1 +#ifdef HAVE_LOCALE_H +#include +#endif + +#define HAVE_WCHAR_H 1 +#ifdef HAVE_WCHAR_H +#include +#endif + +/* configure script should allow user to override ltdl choice, but this will do for now... */ +/* #undef USE_LTDL */ +/* #undef HAVE_LTDL_H */ +#ifdef HAVE_LTDL_H +#define USE_LTDL +#endif + +#ifdef USE_LTDL +#include +#else +#define HAVE_DLFCN_H /**/ +#ifdef HAVE_DLFCN_H +#include +#endif +#endif + + +/* moved to end to prevent AIX compiler warnings */ +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif + + +/***** MARO DEFINITIONS *****/ + +/* this needs to come after all system include files, so we don't accidentally attempt to redefine it */ +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + + +#endif diff --git a/nagios4/defaults.h b/nagios4/defaults.h new file mode 100644 index 0000000..b043775 --- /dev/null +++ b/nagios4/defaults.h @@ -0,0 +1,94 @@ +#ifndef INCLUDE_defaults_h__ +#define INCLUDE_defaults_h__ + +/******************* DEFAULT VALUES *******************/ + +#define DEFAULT_LOG_LEVEL 1 /* log all events to main log file */ +#define DEFAULT_USE_SYSLOG 1 /* log events to syslog? 1=yes, 0=no */ +#define DEFAULT_SYSLOG_LEVEL 2 /* log only severe events to syslog */ + +#define DEFAULT_NOTIFICATION_LOGGING 1 /* log notification events? 1=yes, 0=no */ + +#define DEFAULT_INTER_CHECK_DELAY 5.0 /* seconds between initial service check scheduling */ +#define DEFAULT_INTERLEAVE_FACTOR 1 /* default interleave to use when scheduling checks */ +#define DEFAULT_RETRY_INTERVAL 30 /* services are retried in 30 seconds if they're not OK */ +#define DEFAULT_CHECK_REAPER_INTERVAL 10 /* interval in seconds to reap host and service check results */ +#define DEFAULT_MAX_REAPER_TIME 30 /* maximum number of seconds to spend reaping service checks before we break out for a while */ +#define DEFAULT_MAX_CHECK_RESULT_AGE 3600 /* maximum number of seconds that a check result file is considered to be valid */ +#define DEFAULT_MAX_PARALLEL_SERVICE_CHECKS 0 /* maximum number of service checks we can have running at any given time (0=unlimited) */ +#define DEFAULT_RETENTION_UPDATE_INTERVAL 60 /* minutes between auto-save of retention data */ +#define DEFAULT_RETENTION_SCHEDULING_HORIZON 900 /* max seconds between program restarts that we will preserve scheduling information */ +#define DEFAULT_STATUS_UPDATE_INTERVAL 60 /* seconds between aggregated status data updates */ +#define DEFAULT_FRESHNESS_CHECK_INTERVAL 60 /* seconds between service result freshness checks */ +#define DEFAULT_AUTO_RESCHEDULING_INTERVAL 30 /* seconds between host and service check rescheduling events */ +#define DEFAULT_AUTO_RESCHEDULING_WINDOW 180 /* window of time (in seconds) for which we should reschedule host and service checks */ +#define DEFAULT_ORPHAN_CHECK_INTERVAL 60 /* seconds between checks for orphaned hosts and services */ + +#define DEFAULT_INTERVAL_LENGTH 60 /* seconds per interval unit for check scheduling */ + +#define DEFAULT_NOTIFICATION_TIMEOUT 30 /* max time in seconds to wait for notification commands to complete */ +#define DEFAULT_EVENT_HANDLER_TIMEOUT 30 /* max time in seconds to wait for event handler commands to complete */ +#define DEFAULT_HOST_CHECK_TIMEOUT 30 /* max time in seconds to wait for host check commands to complete */ +#define DEFAULT_SERVICE_CHECK_TIMEOUT 60 /* max time in seconds to wait for service check commands to complete */ +#define DEFAULT_OCSP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_OCHP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_PERFDATA_TIMEOUT 5 /* max time in seconds to wait for performance data commands to complete */ +#define DEFAULT_TIME_CHANGE_THRESHOLD 900 /* compensate for time changes of more than 15 minutes */ + +#define DEFAULT_LOG_HOST_RETRIES 0 /* don't log host retries */ +#define DEFAULT_LOG_SERVICE_RETRIES 0 /* don't log service retries */ +#define DEFAULT_LOG_EVENT_HANDLERS 1 /* log event handlers */ +#define DEFAULT_LOG_INITIAL_STATES 0 /* don't log initial service and host states */ +#define DEFAULT_LOG_CURRENT_STATES 1 /* log current service and host states after rotating log */ +#define DEFAULT_LOG_EXTERNAL_COMMANDS 1 /* log external commands */ +#define DEFAULT_LOG_PASSIVE_CHECKS 1 /* log passive service checks */ + +#define DEFAULT_DEBUG_LEVEL 0 /* don't log any debugging information */ +#define DEFAULT_DEBUG_VERBOSITY 1 +#define DEFAULT_MAX_DEBUG_FILE_SIZE 1000000 /* max size of debug log */ + +#define DEFAULT_AGGRESSIVE_HOST_CHECKING 0 /* don't use "aggressive" host checking */ +#define DEFAULT_CHECK_EXTERNAL_COMMANDS 1 /* check for external commands */ +#define DEFAULT_CHECK_ORPHANED_SERVICES 1 /* check for orphaned services */ +#define DEFAULT_CHECK_ORPHANED_HOSTS 1 /* check for orphaned hosts */ +#define DEFAULT_ENABLE_FLAP_DETECTION 0 /* don't enable flap detection */ +#define DEFAULT_PROCESS_PERFORMANCE_DATA 0 /* don't process performance data */ +#define DEFAULT_CHECK_SERVICE_FRESHNESS 1 /* check service result freshness */ +#define DEFAULT_CHECK_HOST_FRESHNESS 0 /* don't check host result freshness */ +#define DEFAULT_AUTO_RESCHEDULE_CHECKS 0 /* don't auto-reschedule host and service checks */ +#define DEFAULT_TRANSLATE_PASSIVE_HOST_CHECKS 0 /* should we translate DOWN/UNREACHABLE passive host checks? */ +#define DEFAULT_PASSIVE_HOST_CHECKS_SOFT 0 /* passive host checks are treated as HARD by default */ + +#define DEFAULT_LOW_SERVICE_FLAP_THRESHOLD 20.0 /* low threshold for detection of service flapping */ +#define DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD 30.0 /* high threshold for detection of service flapping */ +#define DEFAULT_LOW_HOST_FLAP_THRESHOLD 20.0 /* low threshold for detection of host flapping */ +#define DEFAULT_HIGH_HOST_FLAP_THRESHOLD 30.0 /* high threshold for detection of host flapping */ + +#define DEFAULT_HOST_CHECK_SPREAD 30 /* max minutes to schedule all initial host checks */ +#define DEFAULT_SERVICE_CHECK_SPREAD 30 /* max minutes to schedule all initial service checks */ + +#define DEFAULT_CACHED_HOST_CHECK_HORIZON 15 /* max age in seconds that cached host checks can be used */ +#define DEFAULT_CACHED_SERVICE_CHECK_HORIZON 15 /* max age in seconds that cached service checks can be used */ +#define DEFAULT_ENABLE_PREDICTIVE_HOST_DEPENDENCY_CHECKS 1 /* should we use predictive host dependency checks? */ +#define DEFAULT_ENABLE_PREDICTIVE_SERVICE_DEPENDENCY_CHECKS 1 /* should we use predictive service dependency checks? */ + +#define DEFAULT_USE_LARGE_INSTALLATION_TWEAKS 0 /* don't use tweaks for large Nagios installations */ + +#define DEFAULT_ADDITIONAL_FRESHNESS_LATENCY 15 /* seconds to be added to freshness thresholds when automatically calculated by Nagios */ + +#define DEFAULT_CHECK_FOR_UPDATES 1 /* should we check for new Nagios releases? */ +#define DEFAULT_BARE_UPDATE_CHECK 0 /* report current version and new installs */ +#define MINIMUM_UPDATE_CHECK_INTERVAL 60*60*22 /* 22 hours minimum between checks - please be kind to our servers! */ +#define BASE_UPDATE_CHECK_INTERVAL 60*60*22 /* 22 hours base interval */ +#define UPDATE_CHECK_INTERVAL_WOBBLE 60*60*4 /* 4 hour wobble on top of base interval */ +#define BASE_UPDATE_CHECK_RETRY_INTERVAL 60*60*1 /* 1 hour base retry interval */ +#define UPDATE_CHECK_RETRY_INTERVAL_WOBBLE 60*60*3 /* 3 hour wobble on top of base retry interval */ + +#define DEFAULT_ALLOW_EMPTY_HOSTGROUP_ASSIGNMENT 2 /* Allow assigning to empty hostgroups by default, but warn about it */ + +#define DEFAULT_HOST_PERFDATA_FILE_TEMPLATE "[HOSTPERFDATA]\t$TIMET$\t$HOSTNAME$\t$HOSTEXECUTIONTIME$\t$HOSTOUTPUT$\t$HOSTPERFDATA$" +#define DEFAULT_SERVICE_PERFDATA_FILE_TEMPLATE "[SERVICEPERFDATA]\t$TIMET$\t$HOSTNAME$\t$SERVICEDESC$\t$SERVICEEXECUTIONTIME$\t$SERVICELATENCY$\t$SERVICEOUTPUT$\t$SERVICEPERFDATA$" +#define DEFAULT_HOST_PERFDATA_PROCESS_EMPTY_RESULTS 1 +#define DEFAULT_SERVICE_PERFDATA_PROCESS_EMPTY_RESULTS 1 + +#endif /* INCLUDE_defaults_h__ */ diff --git a/nagios4/dkhash.h b/nagios4/dkhash.h new file mode 100644 index 0000000..e7ae798 --- /dev/null +++ b/nagios4/dkhash.h @@ -0,0 +1,134 @@ +#ifndef LIBNAGIOS_dkhash_h__ +#define LIBNAGIOS_dkhash_h__ +#include + +/** + * @file dkhash.h + * @brief Dual-key hash functions for Nagios + * + * Having a dual-key hash function is pretty unusual, but since so + * much data in Nagios pertains to services (which are uniquely + * identified based on both host_name and service_description), it + * makes sense here. + * + * @{ + */ + +/** return flags usable from the callback function of dkhash_walk_data() */ +#define DKHASH_WALK_REMOVE 1 /**< Remove the most recently visited object */ +#define DKHASH_WALK_STOP 2 /**< Cause walking to stop */ + +/** return values for dkhash_insert() */ +#define DKHASH_OK 0 /**< Success */ +#define DKHASH_EDUPE (-EPERM) /**< duplicate insert attempted */ +#define DKHASH_EPERM (-EPERM) /**< duplicate insert attempted */ +#define DKHASH_EINVAL (-EINVAL) /**< Invalid parameters passed */ +#define DKHASH_ENOMEM (-ENOMEM) /**< Memory allocation failed */ + +struct dkhash_table; +/** opaque type */ +typedef struct dkhash_table dkhash_table; + +/** + * Create a dual-keyed hash-table of the given size + * Note that it's generally useful to make the table 25-30% larger + * than the number of items you intend to store, and also note that + * the 'size' arguments gets rounded up to the nearest power of 2. + * @param size The desired size of the hash-table. + */ +extern dkhash_table *dkhash_create(unsigned int size); + +/** + * Destroy a dual-keyed hash table + * @param t The table to destroy + * @return 0 on success, -1 on errors + */ +extern int dkhash_destroy(dkhash_table *t); + +/** + * Fetch the data associated with a particular key + * @param t The table to get the data from + * @param k1 The first key + * @param k2 The second key + * @return The data on success, NULL on errors or if data isn't found + */ +extern void *dkhash_get(dkhash_table *t, const char *k1, const char *k2); + +/** + * Insert a new entry into the hash table + * @param t The hash table + * @param k1 The first key + * @param k2 The second key (may be null) + * @param data The data to insert + * @return 0 on success, < 0 on errors + */ +extern int dkhash_insert(dkhash_table *t, const char *k1, const char *k2, void *data); + +/** + * Remove data from the hash table + * Note that this does not free() the pointer to the data stored in the + * table. It just destroys containers for that data in the hash table. + * @param t The hash table + * @param k1 The first key + * @param k2 The second key + * @return The removed data on success, or NULL on errors + */ +extern void *dkhash_remove(dkhash_table *t, const char *k1, const char *k2); + +/** + * Call a function once for each item in the hash-table + * The callback function can return DKHASH_WALK_{REMOVE,STOP} or any + * OR'ed combination thereof to control the walking procedure, and + * should return 0 on the normal case. + * @param t The hash table + * @param walker The callback function to send the data to + */ +extern void dkhash_walk_data(dkhash_table *t, int (*walker)(void *data)); + + +/** + * Get number of collisions in hash table + * Many collisions is a sign of a too small hash table or + * poor hash-function. + * @param t The hash table to report on + * @return The total number of collisions (not duplicates) from inserts + */ +extern unsigned int dkhash_collisions(dkhash_table *t); + +/** + * Get number of items in the hash table + * @param t The hash table + * @return Number of items currently in the hash-table + */ +extern unsigned int dkhash_num_entries(dkhash_table *t); + +/** + * Get max number of items stored in the hash table + * @param t The hash table + * @return Max number of items stored in hash-table + */ +extern unsigned int dkhash_num_entries_max(dkhash_table *t); + +/** + * Get number of entries added to hash table + * Note that some of them may have been removed. + * @param t The hash table + * @return The number of items added to the table + */ +extern unsigned int dkhash_num_entries_added(dkhash_table *t); + +/** + * Get number of removed items from hash table + * @param t The hash table + * @return Number of items removed from hash table + */ +extern unsigned int dkhash_num_entries_removed(dkhash_table *t); + +/** + * Get actual table size (in number of buckets) + * @param t The hash table + * @return Number of bucket-slots in hash table + */ +extern unsigned int dkhash_table_size(dkhash_table *t); +/** @} */ +#endif /* LIBNAGIOS_dkhash_h__ */ diff --git a/nagios4/downtime.h b/nagios4/downtime.h new file mode 100644 index 0000000..dfc3af9 --- /dev/null +++ b/nagios4/downtime.h @@ -0,0 +1,112 @@ +/***************************************************************************** + * + * DOWNTIME.H - Header file for scheduled downtime functions + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _DOWNTIME_H +#define _DOWNTIME_H + +#include "common.h" +#include "objects.h" +#ifndef NSCGI +#include "nagios.h" +#endif + +NAGIOS_BEGIN_DECL + +/* SCHEDULED_DOWNTIME_ENTRY structure */ +typedef struct scheduled_downtime { + int type; + char *host_name; + char *service_description; + time_t entry_time; + time_t start_time; + time_t flex_downtime_start; /* Time the flexible downtime started */ + time_t end_time; + int fixed; + unsigned long triggered_by; + unsigned long duration; + unsigned long downtime_id; + int is_in_effect; + int start_notification_sent; + char *author; + char *comment; +#ifndef NSCGI + unsigned long comment_id; + int start_flex_downtime; + int incremented_pending_downtime; +#endif + struct scheduled_downtime *next; +#ifndef NSCGI + struct timed_event *start_event, *stop_event; +#endif + struct scheduled_downtime *prev; + } scheduled_downtime; + +extern struct scheduled_downtime *scheduled_downtime_list; + + +int initialize_downtime_data(void); /* initializes scheduled downtime data */ +int cleanup_downtime_data(void); /* cleans up scheduled downtime data */ + +#ifndef NSCGI +int add_new_downtime(int, char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); +int add_new_host_downtime(char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); +int add_new_service_downtime(char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *, int, int); + +int delete_host_downtime(unsigned long); +int delete_service_downtime(unsigned long); +int delete_downtime(int, unsigned long); + +int schedule_downtime(int, char *, char *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long, unsigned long *); +int unschedule_downtime(int, unsigned long); + +int register_downtime(int, unsigned long); +int handle_scheduled_downtime(struct scheduled_downtime *); +int handle_scheduled_downtime_by_id(unsigned long); + +int check_pending_flex_host_downtime(struct host *); +int check_pending_flex_service_downtime(struct service *); + +int check_for_expired_downtime(void); +#endif + +int add_host_downtime(char *, time_t, char *, char *, time_t, time_t, time_t, int, unsigned long, unsigned long, unsigned long, int, int); +int add_service_downtime(char *, char *, time_t, char *, char *, time_t, time_t, time_t, int, unsigned long, unsigned long, unsigned long, int, int); + +/* If you are going to be adding a lot of downtime in sequence, set + defer_downtime_sorting to 1 before you start and then call + sort_downtime afterwards. Things will go MUCH faster. */ + +extern int defer_downtime_sorting; +int add_downtime(int, char *, char *, time_t, char *, char *, time_t, time_t, time_t, int, unsigned long, unsigned long, unsigned long, int, int); +int sort_downtime(void); + +struct scheduled_downtime *find_downtime(int, unsigned long); +struct scheduled_downtime *find_host_downtime(unsigned long); +struct scheduled_downtime *find_service_downtime(unsigned long); + +void free_downtime_data(void); /* frees memory allocated to scheduled downtime list */ + +int delete_downtime_by_hostname_service_description_start_time_comment(char *, char *, time_t, char *); + +NAGIOS_END_DECL +#endif diff --git a/nagios4/fanout.h b/nagios4/fanout.h new file mode 100644 index 0000000..4a072e5 --- /dev/null +++ b/nagios4/fanout.h @@ -0,0 +1,73 @@ +#ifndef LIBNAGIOS_fanout_h__ +#define LIBNAGIOS_fanout_h__ +#include "lnag-utils.h" + +/** + * @file fanout.h + * @brief Simple fanout table implementation + * + * Fanouts are useful to hold short-lived integer-indexed data where + * the keyspan between smallest and largest key can be too large and + * change too often for it to be practical to maintain a growing array. + * If you think of it as a hash-table optimized for unsigned longs you've + * got the right idea. + * + * @{ + */ + +NAGIOS_BEGIN_DECL + +/** Primary (opaque) type for this api */ +typedef struct fanout_table fanout_table; + +/** + * Create a fanout table + * @param[in] size The size of the table. Preferrably a power of 2 + * @return Pointer to a newly created table + */ +extern fanout_table *fanout_create(unsigned long size); + +/** + * Destroy a fanout table, with optional destructor. + * This function will iterate over all the entries in the fanout + * table and remove them, one by one. If 'destructor' is not NULL, + * it will be called on each and every object in the table. Note that + * 'free' is a valid destructor. + * + * @param[in] t The fanout table to destroy + * @param[in] destructor Function to call on data pointers in table + */ +extern void fanout_destroy(fanout_table *t, void (*destructor)(void *)); + +/** + * Return a pointer from the fanout table t + * + * @param[in] t table to fetch from + * @param[in] key key to fetch + * @return NULL on errors; Pointer to data on success + */ +extern void *fanout_get(fanout_table *t, unsigned long key); + +/** + * Add an entry to the fanout table. + * Note that we don't check if the key is unique. If it isn't, + * fanout_remove() will remove the latest added first. + * + * @param[in] t fanout table to add to + * @param[in] key Key for this entry + * @param[in] data Data to add. Must not be NULL + * @return 0 on success, -1 on errors + */ +extern int fanout_add(fanout_table *t, unsigned long key, void *data); + +/** + * Remove an entry from the fanout table and return its data. + * + * @param[in] t fanout table to look in + * @param[key] The key whose data we should locate + * @return Pointer to the data stored on success; NULL on errors + */ +extern void *fanout_remove(fanout_table *t, unsigned long key); +NAGIOS_END_DECL +/** @} */ +#endif diff --git a/nagios4/iobroker.h b/nagios4/iobroker.h new file mode 100644 index 0000000..f88b04e --- /dev/null +++ b/nagios4/iobroker.h @@ -0,0 +1,175 @@ +/* lib/iobroker.h. Generated from iobroker.h.in by configure. */ +#ifndef LIBNAGIOS_iobroker_h__ +#define LIBNAGIOS_iobroker_h__ + +/** + * @file iobroker.h + * @brief I/O broker library function declarations + * + * The I/O broker library handles multiplexing between hundreds or + * thousands of sockets with a few simple calls. It's designed to + * be as lightweight as possible so as to not cause memory bloat, + * and is therefore highly suitable for use by processes that are + * fork()-intensive. + * + * @{ + */ + +#define IOBROKER_USES_EPOLL 1 +/* #undef IOBROKER_USES_POLL */ +/* #undef IOBROKER_USES_SELECT */ + +#if (_POSIX_C_SOURCE - 0) >= 200112L +#include +# define IOBROKER_POLLIN POLLIN +# define IOBROKER_POLLPRI POLLPRI +# define IOBROKER_POLLOUT POLLOUT + +# define IOBROKER_POLLERR POLLERR +# define IOBROKER_POLLHUP POLLHUP +# define IOBROKER_POLLNVAL POLLNVAL +#else +# define IOBROKER_POLLIN 0x001 /* there is data to read */ +# define IOBROKER_POLLPRI 0x002 /* there is urgent data to read */ +# define IOBROKER_POLLOUT 0x004 /* writing now will not block */ + +# define IOBROKER_POLLERR 0x008 /* error condition */ +# define IOBROKER_POLLHUP 0x010 /* hung up */ +# define IOBROKER_POLLNVAL 0x020 /* invalid polling request */ +#endif + +/** return codes */ +#define IOBROKER_SUCCESS 0 +#define IOBROKER_ENOSET (-1) +#define IOBROKER_ENOINIT (-2) +#define IOBROKER_ELIB (-3) +#define IOBROKER_EALREADY (-EALREADY) +#define IOBROKER_EINVAL (-EINVAL) + + +/** Flags for iobroker_destroy() */ +#define IOBROKER_CLOSE_SOCKETS 1 + +/* Opaque type. Callers needn't worry about this */ +struct iobroker_set; +typedef struct iobroker_set iobroker_set; + +/** + * Get a string describing the error in the last iobroker call. + * The returned string must not be free()'d. + * @param error The error code + * @return A string describing the meaning of the error code + */ +extern const char *iobroker_strerror(int error); + +/** + * Create a new socket set + * @return An iobroker_set on success. NULL on errors. + */ +extern iobroker_set *iobroker_create(void); + +/** + * Published utility function used to determine the max number of + * file descriptors this process can keep open at any one time. + * @return Max number of filedescriptors we can keep open + */ +extern int iobroker_max_usable_fds(void); + +/** + * Register a socket for input polling with the broker. + * + * @param iobs The socket set to add the socket to. + * @param sd The socket descriptor to add + * @param arg Argument passed to input handler on available input + * @param handler The callback function to call when input is available + * + * @return 0 on succes. < 0 on errors. + */ +extern int iobroker_register(iobroker_set *iobs, int sd, void *arg, int (*handler)(int, int, void *)); + + +/** + * Register a socket for output polling with the broker + * @note There's no guarantee that *ALL* data is writable just + * because the socket won't block you completely. + * + * @param iobs The socket set to add the socket to. + * @param sd The socket descriptor to add + * @param arg Argument passed to output handler on ready-to-write + * @param handler The function to call when output won't block + * + * @return 0 on success. < 0 on errors + */ +extern int iobroker_register_out(iobroker_set *iobs, int sd, void *arg, int (*handler)(int, int, void *)); + +/** + * Check if a particular filedescriptor is registered with the iobroker set + * @param[in] iobs The iobroker set the filedescriptor should be member of + * @param[in] fd The filedescriptor to check for + * @return 1 if the filedescriptor is registered and 0 otherwise + */ +extern int iobroker_is_registered(iobroker_set *iobs, int fd); + +/** + * Getter function for number of file descriptors registered in + * the set specified. + * @param iobs The io broker set to query + * @return Number of file descriptors registered in the set + */ +extern int iobroker_get_num_fds(iobroker_set *iobs); + +/** + * Getter function for the maximum amount of file descriptors this + * set can handle. + * @param iobs The io broker set to query + * @return Max file descriptor capacity for the set + */ +extern int iobroker_get_max_fds(iobroker_set *iobs); + +/** + * Unregister a socket for input polling with the broker. + * + * @param iobs The socket set to remove the socket from + * @param sd The socket descriptor to remove + * @return 0 on succes. < 0 on errors. + */ +extern int iobroker_unregister(iobroker_set *iobs, int sd); + +/** + * Deregister a socket for input polling with the broker + * (this is identical to iobroker_unregister()) + * @param iobs The socket set to remove the socket from + * @param sd The socket descriptor to remove + * @return 0 on success. < 0 on errors. + */ +extern int iobroker_deregister(iobroker_set *iobs, int sd); + +/** + * Unregister and close(2) a socket registered for input with the + * broker. This is a convenience function which exists only to avoid + * doing multiple calls when read() returns 0, as closed sockets must + * always be removed from the socket set to avoid consuming tons of + * cpu power from iterating "too fast" over the file descriptors. + * + * @param iobs The socket set to remove the socket from + * @param sd The socket descriptor to remove and close + * @return 0 on success. < 0 on errors + */ +extern int iobroker_close(iobroker_set *iobs, int sd); + +/** + * Destroy a socket set as created by iobroker_create + * @param iobs The socket set to destroy + * @param flags If set, close(2) all registered sockets + */ +extern void iobroker_destroy(iobroker_set *iobs, int flags); + +/** + * Wait for input on any of the registered sockets. + * @param iobs The socket set to wait for. + * @param timeout Timeout in milliseconds. -1 is "wait indefinitely" + * @return -1 on errors, or number of filedescriptors with input + */ +extern int iobroker_poll(iobroker_set *iobs, int timeout); +#endif /* INCLUDE_iobroker_h__ */ +/** @} */ diff --git a/nagios4/iocache.h b/nagios4/iocache.h new file mode 100644 index 0000000..3b040c1 --- /dev/null +++ b/nagios4/iocache.h @@ -0,0 +1,181 @@ +#ifndef LIBNAGIOS_iocache_h__ +#define LIBNAGIOS_iocache_h__ +#include +#include +#include + +/** + * @file iocache.h + * @brief I/O cache function declarations + * + * The I/O cache library is useful for reading large chunks of data + * from sockets and utilizing parts of that data based on either + * size or a magic delimiter. + * + * @{ + */ + +/** opaque type for iocache operations */ +struct iocache; +typedef struct iocache iocache; + +/** + * Destroys an iocache object, freeing all memory allocated to it. + * @param ioc The iocache object to destroy + */ +extern void iocache_destroy(iocache *ioc); + +/** + * Resets an iocache struct, discarding all data in it without free()'ing + * any memory. + * + * @param[in] ioc The iocache struct to reset + */ +extern void iocache_reset(iocache *ioc); + +/** + * Resizes the buffer in an io cache + * @param ioc The io cache to resize + * @param new_size The new size of the io cache + * @return 0 on success, -1 on errors + */ +extern int iocache_resize(iocache *ioc, unsigned long new_size); + +/** + * Grows an iocache object + * This uses iocache_resize() internally + * @param[in] ioc The iocache to grow + * @param[in] increment How much to increase it + * @return 0 on success, -1 on errors + */ +extern int iocache_grow(iocache *ioc, unsigned long increment); + +/** + * Returns the total size of the io cache + * @param[in] ioc The iocache to inspect + * @return The size of the io cache. If ioc is null, 0 is returned + */ +extern unsigned long iocache_size(iocache *ioc); + +/** + * Returns remaining read capacity of the io cache + * @param ioc The io cache to operate on + * @return The number of bytes available to read + */ +extern unsigned long iocache_capacity(iocache *ioc); + +/** + * Return the amount of unread but stored data in the io cache + * @param ioc The io cache to operate on + * @return Number of bytes available to read + */ +extern unsigned long iocache_available(iocache *ioc); + +/** + * Use a chunk of data from iocache based on size. The caller + * must take care not to write beyond the end of the requested + * buffer, or Bad Things(tm) will happen. + * + * @param ioc The io cache we should use data from + * @param size The size of the data we want returned + * @return NULL on errors (insufficient data, fe). pointer on success + */ +extern char *iocache_use_size(iocache *ioc, unsigned long size); + +/** + * Use a chunk of data from iocache based on delimiter. The + * caller must take care not to write beyond the end of the + * requested buffer, if any is returned, or Bad Things(tm) will + * happen. + * + * @param ioc The io cache to use data from + * @param delim The delimiter + * @param delim_len Length of the delimiter + * @param size Length of the returned buffer + * @return NULL on errors (delimiter not found, insufficient data). pointer on success + */ +extern char *iocache_use_delim(iocache *ioc, const char *delim, size_t delim_len, unsigned long *size); + +/** + * Forget that a specified number of bytes have been used. + * @param ioc The io cache that you want to un-use data in + * @param size The number of bytes you want to forget you've seen + * @return -1 if there was an error, 0 otherwise. + */ +extern int iocache_unuse_size(iocache *ioc, unsigned long size); + +/** + * Creates the iocache object, initializing it with the given size + * @param size Initial size of the iocache buffer + * @return Pointer to a valid iocache object + */ +extern iocache *iocache_create(unsigned long size); + +/** + * Read data into the iocache buffer + * @param ioc The io cache we should read into + * @param fd The filedescriptor we should read from + * @return The number of bytes read on success. < 0 on errors + */ +extern int iocache_read(iocache *ioc, int fd); + +/** + * Add data to the iocache buffer + * The data is copied, so it can safely be taken from the stack in a + * function that returns before the data is used. + * If the io cache is too small to hold the data, -1 will be returned. + * + * @param[in] ioc The io cache to add to + * @param[in] buf Pointer to the data we should add + * @param[in] len Length (in bytes) of data pointed to by buf + * @return iocache_available(ioc) on success, -1 on errors + */ +extern int iocache_add(iocache *ioc, char *buf, unsigned int len); + +/** + * Like sendto(), but sends all cached data prior to the requested + * + * @param[in] ioc The iocache to send, or cache data in + * @param[in] fd The file descriptor to send to + * @param[in] buf Pointer to the data to send + * @param[in] len Length (in bytes) of data to send + * @param[in] flags Flags passed to sendto(2) + * @param[in] dest_addr Destination address + * @param[in] addrlen size (in bytes) of dest_addr + * @return bytes sent on success, -ERRNO on errors + */ +extern int iocache_sendto(iocache *ioc, int fd, char *buf, unsigned int len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); + +/** + * Like send(2), but sends all cached data prior to the requested + * This function uses iocache_sendto() internally, but can only be + * used on connected sockets or open()'ed files. + * + * @param[in] ioc The iocache to send, or cache data in + * @param[in] fd The file descriptor to send to + * @param[in] buf Pointer to the data to send + * @param[in] len Length (in bytes) of data to send + * @param[in] flags Flags passed to sendto(2) + * @return bytes sent on success, -ERRNO on errors + */ +static inline int iocache_send(iocache *ioc, int fd, char *buf, unsigned int len, int flags) +{ + return iocache_sendto(ioc, fd, buf, len, flags, NULL, 0); +} + +/** + * Like write(2), but sends all cached data prior to the requested + * This function uses iocache_send() internally. + * + * @param[in] ioc The iocache to send, or cache data in + * @param[in] fd The file descriptor to send to + * @param[in] buf Pointer to the data to send + * @param[in] len Length (in bytes) of data to send + * @return bytes sent on success, -ERRNO on errors + */ +static inline int iocache_write(iocache *ioc, int fd, char *buf, unsigned int len) +{ + return iocache_send(ioc, fd, buf, len, 0); +} +#endif /* INCLUDE_iocache_h__ */ +/** @} */ diff --git a/nagios4/kvvec.h b/nagios4/kvvec.h new file mode 100644 index 0000000..5b693cf --- /dev/null +++ b/nagios4/kvvec.h @@ -0,0 +1,207 @@ +#ifndef LIBNAGIOS_kvvec_h__ +#define LIBNAGIOS_kvvec_h__ + +/** + * @file kvvec.h + * @brief Key/value vector library function and type declarations + * + * The kvvec library is nifty as either a configuration meta-format + * or for IPC purposes. Take a look at the buf2kvvec() and kvvec2buf() + * pair of functions for the latter. + * @{ + */ + +/** + * key/value pair + * One of the two major components of the kvvec api + */ +struct key_value { + char *key; /**< The key */ + char *value; /**< The value */ + int key_len; /**< Length of key */ + int value_len; /**< Length of value */ +}; + +/** + * key/value vector buffer. Actually just a buffer, but one that gets + * used as return value and internal tracker for kvvec2buf() + */ +struct kvvec_buf { + char *buf; /**< The buffer */ + unsigned long buflen; /**< Length of buffer */ + unsigned long bufsize; /**< Size of buffer (includes overalloc) */ +}; + +/** + * key/value vector struct + * This is the main component of the kvvec library + * @note This should be made opaque, with a kvvec_foreach() using a + * callback to iterate over key/value pairs. + */ +struct kvvec { + struct key_value *kv; /**< The key/value array */ + int kv_alloc; /**< Allocated size of key/value array */ + int kv_pairs; /**< Number of key/value pairs */ + int kvv_sorted; /**< Determines if this kvvec has been sorted */ +}; + +/** Portable initializer for stack-allocated key/value vectors */ +#define KVVEC_INITIALIZER { NULL, 0, 0, 0 } + +/** Parameters for kvvec_destroy() */ +#define KVVEC_FREE_KEYS 1 /**< Free keys when destroying a kv vector */ +#define KVVEC_FREE_VALUES 2 /**< Free values when destroying a kv vector */ +/** Free both keys and values when destroying a kv vector */ +#define KVVEC_FREE_ALL (KVVEC_FREE_KEYS | KVVEC_FREE_VALUES) + +#define KVVEC_ASSIGN 0 /**< Assign from buf in buf2kvvec_prealloc() */ +#define KVVEC_COPY 1 /**< Copy from buf in buf2kvvec_prealloc() */ +#define KVVEC_APPEND 2 /**< Don't reset kvvec in buf2kvvec_prealloc() */ + +/** + * Initialize a previously allocated key/value vector + * + * @param kvv The key/value vector to initialize + * @param hint Number of key/value pairs we expect to store + * @return Pointer to a struct kvvec, properly initialized + */ +extern struct kvvec *kvvec_init(struct kvvec *kvv, int hint); + +/** + * Create a key/value vector + * + * @param hint Number of key/value pairs we expect to store + * @return Pointer to a struct kvvec, properly initialized + */ +extern struct kvvec *kvvec_create(int hint); + +/** + * Resize a key/value vector + * Used by kvvec_grow(). If size is smaller than the current number of + * used key/value slots, -1 is returned. + * + * @param[in] kvv The key/value vector to resize + * @param[in] size The size to grow to + * @return 0 on success, < 0 on errors + */ +extern int kvvec_resize(struct kvvec *kvv, int size); + +/** + * Grow a key/value vector. + * Used internally as needed by the kvvec api. If 'hint' is zero, the + * key/value capacity is increased by a third of the current capacity + * plus a small constant number. This uses kvvec_resize() internally. + * + * @param kvv The key/value vector to grow + * @param hint The amount of key/value slots we should grow by + * @return 0 on success, < 0 on errors + */ +extern int kvvec_grow(struct kvvec *kvv, int hint); + +/** + * Return remaining storage capacity of key/value vector + * @param[in] kvv The key/value vector to check + * @return Number of key/value pairs that can be stored without growing + */ +extern unsigned int kvvec_capacity(struct kvvec *kvv); + +/** + * Sort a key/value vector alphabetically by key name + * @param kvv The key/value vector to sort + * @return 0 + */ +extern int kvvec_sort(struct kvvec *kvv); + +/** + * Add a key/value pair to an existing key/value vector, with + * lengths of strings already calculated + * @param kvv The key/value vector to add this key/value pair to + * @param key The key + * @param keylen Length of the key + * @param value The value + * @param valuelen Length of the value + * @return 0 on success, < 0 on errors + */ +extern int kvvec_addkv_wlen(struct kvvec *kvv, const char *key, int keylen, const char *value, int valuelen); + +/** + * Shortcut to kvvec_addkv_wlen() when lengths aren't known + * @param kvv The key/value vector to add this key/value pair to + * @param key The key + * @param value The value + * @return 0 on success, < 0 on errors + */ +#define kvvec_addkv(kvv, key, value) kvvec_addkv_wlen(kvv, key, 0, value, 0) + +/** + * Walk each key/value pair in a key/value vector, sending them + * as arguments to a callback function. The callback function has + * no control over the iteration process and must not delete or + * modify the key/value vector it's operating on. + * @param kvv The key/value vector to walk + * @param arg Extra argument to the callback function + * @param callback Callback function + * @return 0 on success, < 0 on errors + */ +extern int kvvec_foreach(struct kvvec *kvv, void *arg, int (*callback)(struct key_value *, void *)); + +/** + * Destroy a key/value vector + * @param kvv The key/value vector to destroy + * @param flags or'ed combination of KVVEC_FREE_{KEYS,VALUES}, or KVVEC_FREE_ALL + * @return 0 on success, < 0 on errors + */ +extern int kvvec_destroy(struct kvvec *kvv, int flags); + +/** + * Free key/value pairs associated with a key/value vector + * @param kvv The key/value vector to operate on + * @param flags flags or'ed combination of KVVEC_FREE_{KEYS,VALUES}, or KVVEC_FREE_ALL + */ +void kvvec_free_kvpairs(struct kvvec *kvv, int flags); + +/** + * Create a linear buffer of all the key/value pairs and + * return it as a kvvec_buf. The caller must free() all + * pointers in the returned kvvec_buf + * (FIXME: add kvvec_buf_destroy(), or move this and its counterpart + * out of the kvvec api into a separate one) + * + * @param kvv The key/value vector to convert + * @param kv_sep Character separating keys and their values + * @param pair_sep Character separating key/value pairs + * @param overalloc Integer determining how much extra data we should + * allocate. The overallocated memory is filled with + * nul bytes. + * @return A pointer to a newly created kvvec_buf structure + */ +extern struct kvvec_buf *kvvec2buf(struct kvvec *kvv, char kv_sep, char pair_sep, int overalloc); + +/** + * Create a key/value vector from a pre-parsed buffer. Immensely + * useful for ipc in combination with kvvec2buf(). + * + * @param str The buffer to convert to a key/value vector + * @param len Length of buffer to convert + * @param kvsep Character separating key and value + * @param pair_sep Character separating key/value pairs + * @param flags bitmask. See KVVEC_{ASSIGN,COPY,APPEND} for values + * @return The created key/value vector + */ +extern struct kvvec *buf2kvvec(char *str, unsigned int len, const char kvsep, const char pair_sep, int flags); + +/** + * Parse a buffer into the pre-allocated key/value vector. Immensely + * useful for ipc in combination with kvvec2buf(). + * + * @param kvv A pre-allocated key/value vector to populate + * @param str The buffer to convert to a key/value vector + * @param len Length of buffer to convert + * @param kvsep Character separating key and value + * @param pair_sep Character separating key/value pairs + * @param flags bitmask. See KVVEC_{ASSIGN,COPY,APPEND} for values + * @return The number of pairs in the created key/value vector + */ +extern int buf2kvvec_prealloc(struct kvvec *kvv, char *str, unsigned int len, const char kvsep, const char pair_sep, int flags); +/** @} */ +#endif /* INCLUDE_kvvec_h__ */ diff --git a/nagios4/libnagios.h b/nagios4/libnagios.h new file mode 100644 index 0000000..fc7eb47 --- /dev/null +++ b/nagios4/libnagios.h @@ -0,0 +1,25 @@ +#ifndef LIBNAGIOS_libnagios_h__ +#define LIBNAGIOS_libnagios_h__ +/** + * @file libnagios.h + * + * @brief Include this for all public parts of libnagios to be accessible + */ + +#include "lnag-utils.h" +#include "fanout.h" +#include "nsutils.h" +#include "pqueue.h" +#include "squeue.h" +#include "kvvec.h" +#include "iobroker.h" +#include "iocache.h" +#include "runcmd.h" +#include "bitmap.h" +#include "dkhash.h" +#include "worker.h" +#include "skiplist.h" +#include "nsock.h" +#include "nspath.h" +#include "snprintf.h" +#endif /* LIB_libnagios_h__ */ diff --git a/nagios4/lnag-utils.h b/nagios4/lnag-utils.h new file mode 100644 index 0000000..7158044 --- /dev/null +++ b/nagios4/lnag-utils.h @@ -0,0 +1,111 @@ +#ifndef LIBNAGIOS_lnag_utils_h__ +#define LIBNAGIOS_lnag_utils_h__ + +#include /* for sysconf() */ +#include /* for rand() */ + +/** + * @file lnag-utils.h + * @brief libnagios helper and compatibility macros that lack a "real" home. + * + * This is the home of random macros that must be present for compilation + * to succeed but are missing on some platforms. + * + * @{ + */ + +#define NAGIOS_MKVERSION(a, b, c) \ + (((a) * 10000) + ((b) * 100) + (c)) + +#ifdef __cplusplus +/** C++ compatibility macro that avoids confusing indentation programs */ +# define NAGIOS_BEGIN_DECL extern "C" { +/** + * Use at end of header file declarations to obtain C++ compatibility + * ... without confusing indentation programs + */ +# define NAGIOS_END_DECL } +#else +/** C++ compatibility macro that avoids confusing indentation programs */ +# define NAGIOS_BEGIN_DECL /* nothing */ +/** C++ compatibility macro that avoid confusing indentation programs */ +# define NAGIOS_END_DECL /* more of nothing */ +#endif + +#ifndef NODOXY /* doxy comments are useless here */ +# ifndef __GNUC__ +# define GCC_VERSION 0 +# define __attribute__(x) /* nothing */ +# else +# ifdef __GNUC_PATCHLEVEL__ +# define GCC_VERSION NAGIOS_MKVERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +# else +# define GCC_VERSION NAGIOS_MKVERSION(__GNUC__, __GNUC_MINOR__, 0) +# endif /* __GNUC_PATCHLEVEL__ */ +# endif /* __GNUC__ */ +#endif /* NODOXY */ + +#if GCC_VERSION >= NAGIOS_MKVERSION(4, 5, 0) +# define NAGIOS_DEPRECATED(version, hint) \ + __attribute__((deprecated("This function will be removed in Nagios v" #version ". Please use " #hint " instead"))) +#else +/** Macro for alerting module authors to function deprecation */ +# define NAGIOS_DEPRECATED(version, hint) \ + __attribute__((deprecated)) +#endif + +/* + * These macros are widely used throughout Nagios + */ +#define OK 0 /**< Indicates successful function call in Nagios */ +#define ERROR -2 /**< Non-successful function call in Nagios */ + +#ifdef FALSE +#undef FALSE +#endif +#define FALSE 0 /**< Not true */ + +#ifdef TRUE +#undef TRUE +#endif +#define TRUE (!FALSE) /**< Not false */ + +/** Useful macro to safely avoid double-free memory corruption */ +#define my_free(ptr) do { if(ptr) { free(ptr); ptr = NULL; } } while(0) + +#ifndef ARRAY_SIZE +/** Useful for iterating over all elements in a static array */ +# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif +#ifndef veclen +/** useful for iterating over all elements in a static array */ +# define veclen ARRAY_SIZE +#endif + +#ifndef offsetof +/** standard offsetof macro */ +# define offsetof(t, f) ((unsigned long)&((t *)0)->f) +#endif + +/** character map initialization for .bss-allocated char maps */ +#define CHAR_MAP_INIT(k) { \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, k, \ + } + +/** @} */ +#endif diff --git a/nagios4/locations.h b/nagios4/locations.h new file mode 100644 index 0000000..3f41828 --- /dev/null +++ b/nagios4/locations.h @@ -0,0 +1,41 @@ +/************************************************************************ + * + * Nagios Locations Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#define DEFAULT_TEMP_FILE "/usr/local/nagios/var/tempfile" +#define DEFAULT_TEMP_PATH "/tmp" +#define DEFAULT_CHECK_RESULT_PATH "/usr/local/nagios/var/spool/checkresults" +#define DEFAULT_STATUS_FILE "/usr/local/nagios/var/status.dat" +#define DEFAULT_LOG_FILE "/usr/local/nagios/var/nagios.log" +#define DEFAULT_LOG_ARCHIVE_PATH "/usr/local/nagios/var/archives/" +#define DEFAULT_DEBUG_FILE "/usr/local/nagios/var/nagios.debug" +#define DEFAULT_COMMENT_FILE "/usr/local/nagios/var/comments.dat" +#define DEFAULT_DOWNTIME_FILE "/usr/local/nagios/var/downtime.dat" +#define DEFAULT_RETENTION_FILE "/usr/local/nagios/var/retention.dat" +#define DEFAULT_COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd" +#define DEFAULT_QUERY_SOCKET "/usr/local/nagios/var/rw/nagios.qh" +#define DEFAULT_CONFIG_FILE "/usr/local/nagios/etc/nagios.cfg" +#define DEFAULT_PHYSICAL_HTML_PATH "/usr/local/nagios/share" +#define DEFAULT_URL_HTML_PATH "/nagios" +#define DEFAULT_PHYSICAL_CGIBIN_PATH "/usr/local/nagios/sbin" +#define DEFAULT_URL_CGIBIN_PATH "/nagios/cgi-bin" +#define DEFAULT_CGI_CONFIG_FILE "/usr/local/nagios/etc/cgi.cfg" +#define DEFAULT_LOCK_FILE "/usr/local/nagios/var/nagios.lock" +#define DEFAULT_OBJECT_CACHE_FILE "/usr/local/nagios/var/objects.cache" +#define DEFAULT_PRECACHED_OBJECT_FILE "/usr/local/nagios/var/objects.precache" +#define DEFAULT_EVENT_BROKER_FILE "/usr/local/nagios/var/broker.socket" diff --git a/nagios4/logging.h b/nagios4/logging.h new file mode 100644 index 0000000..49b97dc --- /dev/null +++ b/nagios4/logging.h @@ -0,0 +1,90 @@ +#ifndef INCLUDE_logging_h__ +#define INCLUDE_logging_h__ + +#include "objects.h" + +/******************* LOGGING TYPES ********************/ + +#define NSLOG_RUNTIME_ERROR 1 +#define NSLOG_RUNTIME_WARNING 2 + +#define NSLOG_VERIFICATION_ERROR 4 +#define NSLOG_VERIFICATION_WARNING 8 + +#define NSLOG_CONFIG_ERROR 16 +#define NSLOG_CONFIG_WARNING 32 + +#define NSLOG_PROCESS_INFO 64 +#define NSLOG_EVENT_HANDLER 128 +/*#define NSLOG_NOTIFICATION 256*/ /* NOT USED ANYMORE - CAN BE REUSED */ +#define NSLOG_EXTERNAL_COMMAND 512 + +#define NSLOG_HOST_UP 1024 +#define NSLOG_HOST_DOWN 2048 +#define NSLOG_HOST_UNREACHABLE 4096 + +#define NSLOG_SERVICE_OK 8192 +#define NSLOG_SERVICE_UNKNOWN 16384 +#define NSLOG_SERVICE_WARNING 32768 +#define NSLOG_SERVICE_CRITICAL 65536 + +#define NSLOG_PASSIVE_CHECK 131072 + +#define NSLOG_INFO_MESSAGE 262144 + +#define NSLOG_HOST_NOTIFICATION 524288 +#define NSLOG_SERVICE_NOTIFICATION 1048576 + +/***************** DEBUGGING LEVELS *******************/ + +#define DEBUGL_ALL -1 +#define DEBUGL_NONE 0 +#define DEBUGL_FUNCTIONS 1 +#define DEBUGL_CONFIG 2 +#define DEBUGL_PROCESS 4 +#define DEBUGL_STATUSDATA 4 +#define DEBUGL_RETENTIONDATA 4 +#define DEBUGL_EVENTS 8 +#define DEBUGL_CHECKS 16 +#define DEBUGL_FLAPPING 16 +#define DEBUGL_EVENTHANDLERS 16 +#define DEBUGL_PERFDATA 16 +#define DEBUGL_NOTIFICATIONS 32 +#define DEBUGL_EVENTBROKER 64 +#define DEBUGL_EXTERNALCOMMANDS 128 +#define DEBUGL_COMMANDS 256 +#define DEBUGL_DOWNTIME 512 +#define DEBUGL_COMMENTS 1024 +#define DEBUGL_MACROS 2048 +#define DEBUGL_IPC 4096 +#define DEBUGL_SCHEDULING 8192 + +#define DEBUGV_BASIC 0 +#define DEBUGV_MORE 1 +#define DEBUGV_MOST 2 + +NAGIOS_BEGIN_DECL +/**** Logging Functions ****/ +void logit(int, int, const char *, ...) +__attribute__((__format__(__printf__, 3, 4))); +int log_debug_info(int, int, const char *, ...) +__attribute__((__format__(__printf__, 3, 4))); + +#ifndef NSCGI +int write_to_all_logs(char *, unsigned long); /* writes a string to main log file and syslog facility */ +int write_to_log(char *, unsigned long, time_t *); /* write a string to the main log file */ +int write_to_syslog(char *, unsigned long); /* write a string to the syslog facility */ +int log_service_event(service *); /* logs a service event */ +int log_host_event(host *); /* logs a host event */ +int log_host_states(int, time_t *); /* logs initial/current host states */ +int log_service_states(int, time_t *); /* logs initial/current service states */ +int rotate_log_file(time_t); /* rotates the main log file */ +int write_log_file_info(time_t *); /* records log file/version info */ +int open_debug_log(void); +int close_debug_log(void); +int close_log_file(void); +int fix_log_file_owner(uid_t uid, gid_t gid); +#endif /* !NSCGI */ + +NAGIOS_END_DECL +#endif diff --git a/nagios4/macros.h b/nagios4/macros.h new file mode 100644 index 0000000..5b79465 --- /dev/null +++ b/nagios4/macros.h @@ -0,0 +1,339 @@ +/************************************************************************ + * + * MACROS.H - Common macro functions + * Written By: Ethan Galstad (egalstad@nagios.org) + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _MACROS_H +#define _MACROS_H + +#include "common.h" +#include "objects.h" + + + +/****************** LENGTH LIMITATIONS ****************/ + +#define MAX_COMMAND_ARGUMENTS 32 /* maximum number of $ARGx$ macros */ + + +/****************** MACRO DEFINITIONS *****************/ + +#define MACRO_ENV_VAR_PREFIX "NAGIOS_" + +#define MAX_USER_MACROS 256 /* maximum number of $USERx$ macros */ + +#define MACRO_X_COUNT 156 /* size of macro_x[] array */ + +NAGIOS_BEGIN_DECL + +struct nagios_macros { + char *x[MACRO_X_COUNT]; + char *argv[MAX_COMMAND_ARGUMENTS]; + char *contactaddress[MAX_CONTACT_ADDRESSES]; + char *ondemand; + host *host_ptr; + hostgroup *hostgroup_ptr; + service *service_ptr; + servicegroup *servicegroup_ptr; + contact *contact_ptr; + contactgroup *contactgroup_ptr; + customvariablesmember *custom_host_vars; + customvariablesmember *custom_service_vars; + customvariablesmember *custom_contact_vars; + }; +typedef struct nagios_macros nagios_macros; + + + +#define MACRO_HOSTNAME 0 +#define MACRO_HOSTALIAS 1 +#define MACRO_HOSTADDRESS 2 +#define MACRO_SERVICEDESC 3 +#define MACRO_SERVICESTATE 4 +#define MACRO_SERVICESTATEID 5 +#define MACRO_SERVICEATTEMPT 6 +#define MACRO_LONGDATETIME 7 +#define MACRO_SHORTDATETIME 8 +#define MACRO_DATE 9 +#define MACRO_TIME 10 +#define MACRO_TIMET 11 +#define MACRO_LASTHOSTCHECK 12 +#define MACRO_LASTSERVICECHECK 13 +#define MACRO_LASTHOSTSTATECHANGE 14 +#define MACRO_LASTSERVICESTATECHANGE 15 +#define MACRO_HOSTOUTPUT 16 +#define MACRO_SERVICEOUTPUT 17 +#define MACRO_HOSTPERFDATA 18 +#define MACRO_SERVICEPERFDATA 19 +#define MACRO_CONTACTNAME 20 +#define MACRO_CONTACTALIAS 21 +#define MACRO_CONTACTEMAIL 22 +#define MACRO_CONTACTPAGER 23 +#define MACRO_ADMINEMAIL 24 +#define MACRO_ADMINPAGER 25 +#define MACRO_HOSTSTATE 26 +#define MACRO_HOSTSTATEID 27 +#define MACRO_HOSTATTEMPT 28 +#define MACRO_NOTIFICATIONTYPE 29 +#define MACRO_NOTIFICATIONNUMBER 30 /* deprecated - see HOSTNOTIFICATIONNUMBER and SERVICENOTIFICATIONNUMBER macros */ +#define MACRO_HOSTEXECUTIONTIME 31 +#define MACRO_SERVICEEXECUTIONTIME 32 +#define MACRO_HOSTLATENCY 33 +#define MACRO_SERVICELATENCY 34 +#define MACRO_HOSTDURATION 35 +#define MACRO_SERVICEDURATION 36 +#define MACRO_HOSTDURATIONSEC 37 +#define MACRO_SERVICEDURATIONSEC 38 +#define MACRO_HOSTDOWNTIME 39 +#define MACRO_SERVICEDOWNTIME 40 +#define MACRO_HOSTSTATETYPE 41 +#define MACRO_SERVICESTATETYPE 42 +#define MACRO_HOSTPERCENTCHANGE 43 +#define MACRO_SERVICEPERCENTCHANGE 44 +#define MACRO_HOSTGROUPNAME 45 +#define MACRO_HOSTGROUPALIAS 46 +#define MACRO_SERVICEGROUPNAME 47 +#define MACRO_SERVICEGROUPALIAS 48 +#define MACRO_HOSTACKAUTHOR 49 +#define MACRO_HOSTACKCOMMENT 50 +#define MACRO_SERVICEACKAUTHOR 51 +#define MACRO_SERVICEACKCOMMENT 52 +#define MACRO_LASTSERVICEOK 53 +#define MACRO_LASTSERVICEWARNING 54 +#define MACRO_LASTSERVICEUNKNOWN 55 +#define MACRO_LASTSERVICECRITICAL 56 +#define MACRO_LASTHOSTUP 57 +#define MACRO_LASTHOSTDOWN 58 +#define MACRO_LASTHOSTUNREACHABLE 59 +#define MACRO_SERVICECHECKCOMMAND 60 +#define MACRO_HOSTCHECKCOMMAND 61 +#define MACRO_MAINCONFIGFILE 62 +#define MACRO_STATUSDATAFILE 63 +#define MACRO_HOSTDISPLAYNAME 64 +#define MACRO_SERVICEDISPLAYNAME 65 +#define MACRO_RETENTIONDATAFILE 66 +#define MACRO_OBJECTCACHEFILE 67 +#define MACRO_TEMPFILE 68 +#define MACRO_LOGFILE 69 +#define MACRO_RESOURCEFILE 70 +#define MACRO_COMMANDFILE 71 +#define MACRO_HOSTPERFDATAFILE 72 +#define MACRO_SERVICEPERFDATAFILE 73 +#define MACRO_HOSTACTIONURL 74 +#define MACRO_HOSTNOTESURL 75 +#define MACRO_HOSTNOTES 76 +#define MACRO_SERVICEACTIONURL 77 +#define MACRO_SERVICENOTESURL 78 +#define MACRO_SERVICENOTES 79 +#define MACRO_TOTALHOSTSUP 80 +#define MACRO_TOTALHOSTSDOWN 81 +#define MACRO_TOTALHOSTSUNREACHABLE 82 +#define MACRO_TOTALHOSTSDOWNUNHANDLED 83 +#define MACRO_TOTALHOSTSUNREACHABLEUNHANDLED 84 +#define MACRO_TOTALHOSTPROBLEMS 85 +#define MACRO_TOTALHOSTPROBLEMSUNHANDLED 86 +#define MACRO_TOTALSERVICESOK 87 +#define MACRO_TOTALSERVICESWARNING 88 +#define MACRO_TOTALSERVICESCRITICAL 89 +#define MACRO_TOTALSERVICESUNKNOWN 90 +#define MACRO_TOTALSERVICESWARNINGUNHANDLED 91 +#define MACRO_TOTALSERVICESCRITICALUNHANDLED 92 +#define MACRO_TOTALSERVICESUNKNOWNUNHANDLED 93 +#define MACRO_TOTALSERVICEPROBLEMS 94 +#define MACRO_TOTALSERVICEPROBLEMSUNHANDLED 95 +#define MACRO_PROCESSSTARTTIME 96 +#define MACRO_HOSTCHECKTYPE 97 +#define MACRO_SERVICECHECKTYPE 98 +#define MACRO_LONGHOSTOUTPUT 99 +#define MACRO_LONGSERVICEOUTPUT 100 +#define MACRO_TEMPPATH 101 +#define MACRO_HOSTNOTIFICATIONNUMBER 102 +#define MACRO_SERVICENOTIFICATIONNUMBER 103 +#define MACRO_HOSTNOTIFICATIONID 104 +#define MACRO_SERVICENOTIFICATIONID 105 +#define MACRO_HOSTEVENTID 106 +#define MACRO_LASTHOSTEVENTID 107 +#define MACRO_SERVICEEVENTID 108 +#define MACRO_LASTSERVICEEVENTID 109 +#define MACRO_HOSTGROUPNAMES 110 +#define MACRO_SERVICEGROUPNAMES 111 +#define MACRO_HOSTACKAUTHORNAME 112 +#define MACRO_HOSTACKAUTHORALIAS 113 +#define MACRO_SERVICEACKAUTHORNAME 114 +#define MACRO_SERVICEACKAUTHORALIAS 115 +#define MACRO_MAXHOSTATTEMPTS 116 +#define MACRO_MAXSERVICEATTEMPTS 117 +#define MACRO_SERVICEISVOLATILE 118 +#define MACRO_TOTALHOSTSERVICES 119 +#define MACRO_TOTALHOSTSERVICESOK 120 +#define MACRO_TOTALHOSTSERVICESWARNING 121 +#define MACRO_TOTALHOSTSERVICESUNKNOWN 122 +#define MACRO_TOTALHOSTSERVICESCRITICAL 123 +#define MACRO_HOSTGROUPNOTES 124 +#define MACRO_HOSTGROUPNOTESURL 125 +#define MACRO_HOSTGROUPACTIONURL 126 +#define MACRO_SERVICEGROUPNOTES 127 +#define MACRO_SERVICEGROUPNOTESURL 128 +#define MACRO_SERVICEGROUPACTIONURL 129 +#define MACRO_HOSTGROUPMEMBERS 130 +#define MACRO_SERVICEGROUPMEMBERS 131 +#define MACRO_CONTACTGROUPNAME 132 +#define MACRO_CONTACTGROUPALIAS 133 +#define MACRO_CONTACTGROUPMEMBERS 134 +#define MACRO_CONTACTGROUPNAMES 135 +#define MACRO_NOTIFICATIONRECIPIENTS 136 +#define MACRO_NOTIFICATIONISESCALATED 137 +#define MACRO_NOTIFICATIONAUTHOR 138 +#define MACRO_NOTIFICATIONAUTHORNAME 139 +#define MACRO_NOTIFICATIONAUTHORALIAS 140 +#define MACRO_NOTIFICATIONCOMMENT 141 +#define MACRO_EVENTSTARTTIME 142 +#define MACRO_HOSTPROBLEMID 143 +#define MACRO_LASTHOSTPROBLEMID 144 +#define MACRO_SERVICEPROBLEMID 145 +#define MACRO_LASTSERVICEPROBLEMID 146 +#define MACRO_ISVALIDTIME 147 +#define MACRO_NEXTVALIDTIME 148 +#define MACRO_LASTHOSTSTATE 149 +#define MACRO_LASTHOSTSTATEID 150 +#define MACRO_LASTSERVICESTATE 151 +#define MACRO_LASTSERVICESTATEID 152 +#define MACRO_HOSTVALUE 153 +#define MACRO_SERVICEVALUE 154 +#define MACRO_PROBLEMVALUE 155 + + +/************* MACRO CLEANING OPTIONS *****************/ + +#define STRIP_ILLEGAL_MACRO_CHARS 1 +#define ESCAPE_MACRO_CHARS 2 +#define URL_ENCODE_MACRO_CHARS 4 + + + +/****************** MACRO FUNCTIONS ******************/ + +nagios_macros *get_global_macros(void); + +/* + * Replace macros with their actual values + * This function modifies the global_macros struct and is thus + * not thread-safe. + */ +int process_macros(char *, char **, int); + +/* thread-safe version of the above */ +int process_macros_r(nagios_macros *mac, char *, char **, int); + +/* cleans macros characters before insertion into output string */ +char *clean_macro_chars(char *, int); + +/* + * These functions updates **macros with the values from + * their respective object type. + */ + +int grab_service_macros(service *); +int grab_host_macros(host *); +int grab_servicegroup_macros(servicegroup *); +int grab_hostgroup_macros(hostgroup *); +int grab_contact_macros(contact *); + +int grab_macro_value(char *, char **, int *, int *); +int grab_macrox_value(int, char *, char *, char **, int *); +int grab_custom_macro_value(char *, char *, char *, char **); +int grab_datetime_macro(int, char *, char *, char **); +int grab_standard_host_macro(int, host *, char **, int *); +int grab_standard_hostgroup_macro(int, hostgroup *, char **); +int grab_standard_service_macro(int, service *, char **, int *); +int grab_standard_servicegroup_macro(int, servicegroup *, char **); +int grab_standard_contact_macro(int, contact *, char **); +int grab_contact_address_macro(int, contact *, char **); +int grab_standard_contactgroup_macro(int, contactgroup *, char **); +int grab_custom_object_macro(char *, customvariablesmember *, char **); + +/* thread-safe version of the above */ +int grab_service_macros_r(nagios_macros *mac, service *); +int grab_host_macros_r(nagios_macros *mac, host *); +int grab_servicegroup_macros_r(nagios_macros *mac, servicegroup *); +int grab_hostgroup_macros_r(nagios_macros *mac, hostgroup *); +int grab_contact_macros_r(nagios_macros *mac, contact *); + +int grab_macro_value_r(nagios_macros *mac, char *, char **, int *, int *); +int grab_macrox_value_r(nagios_macros *mac, int, char *, char *, char **, int *); +int grab_custom_macro_value_r(nagios_macros *mac, char *, char *, char *, char **); +int grab_datetime_macro_r(nagios_macros *mac, int, char *, char *, char **); +int grab_standard_host_macro_r(nagios_macros *mac, int, host *, char **, int *); +int grab_standard_hostgroup_macro_r(nagios_macros *mac, int, hostgroup *, char **); +int grab_standard_service_macro_r(nagios_macros *mac, int, service *, char **, int *); +int grab_standard_servicegroup_macro_r(nagios_macros *mac, int, servicegroup *, char **); +int grab_standard_contact_macro_r(nagios_macros *mac, int, contact *, char **); +int grab_custom_object_macro_r(nagios_macros *mac, char *, customvariablesmember *, char **); + + +char *get_url_encoded_string(char *); /* URL encode a string */ + +int init_macros(void); +int init_macrox_names(void); +int free_macrox_names(void); + +extern void copy_constant_macros(char **dest); + +/* clear macros */ +int clear_argv_macros(void); +int clear_volatile_macros(void); +int clear_host_macros(void); +int clear_service_macros(void); +int clear_hostgroup_macros(void); +int clear_servicegroup_macros(void); +int clear_contact_macros(void); +int clear_contactgroup_macros(void); +int clear_summary_macros(void); + +/* thread-safe version of the above */ +int clear_argv_macros_r(nagios_macros *mac); +int clear_volatile_macros_r(nagios_macros *mac); +int clear_host_macros_r(nagios_macros *mac); +int clear_service_macros_r(nagios_macros *mac); +int clear_hostgroup_macros_r(nagios_macros *mac); +int clear_servicegroup_macros_r(nagios_macros *mac); +int clear_contact_macros_r(nagios_macros *mac); +int clear_contactgroup_macros_r(nagios_macros *mac); +int clear_summary_macros_r(nagios_macros *mac); + + +#ifndef NSCGI +int set_all_macro_environment_vars(int); +int set_macrox_environment_vars(int); +int set_argv_macro_environment_vars(int); +int set_custom_macro_environment_vars(int); +int set_contact_address_environment_vars(int); +int set_macro_environment_var(char *, char *, int); + +/* thread-safe version of the above */ +int set_all_macro_environment_vars_r(nagios_macros *mac, int); +int set_macrox_environment_vars_r(nagios_macros *mac, int); +int set_argv_macro_environment_vars_r(nagios_macros *mac, int); +int set_custom_macro_environment_vars_r(nagios_macros *mac, int); +int set_contact_address_environment_vars_r(nagios_macros *mac, int); + +#endif + +NAGIOS_END_DECL +#endif diff --git a/nagios4/nagios.h b/nagios4/nagios.h new file mode 100644 index 0000000..1893ca8 --- /dev/null +++ b/nagios4/nagios.h @@ -0,0 +1,756 @@ +/************************************************************************ + * + * Nagios Main Header File + * Written By: Ethan Galstad (egalstad@nagios.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _NAGIOS_H +#define _NAGIOS_H + +#ifndef NSCORE +# define NSCORE +#endif + +#include "defaults.h" +#include "common.h" +#include "logging.h" +#include "locations.h" +#include "objects.h" +#include "macros.h" +#include "config.h" + +/* + * global variables only used in the core. Reducing this list would be + * a Good Thing(tm). + */ +extern char *nagios_binary_path; +extern char *config_file; +extern char *command_file; +extern char *temp_file; +extern char *temp_path; +extern char *check_result_path; +extern char *lock_file; +extern char *object_precache_file; + +extern unsigned int nofile_limit, nproc_limit, max_apps; + +extern int num_check_workers; +extern char *qh_socket_path; + +extern char *nagios_user; +extern char *nagios_group; + +extern char *macro_user[MAX_USER_MACROS]; + +extern char *ocsp_command; +extern char *ochp_command; +extern command *ocsp_command_ptr; +extern command *ochp_command_ptr; +extern int ocsp_timeout; +extern int ochp_timeout; + +extern char *global_host_event_handler; +extern char *global_service_event_handler; +extern command *global_host_event_handler_ptr; +extern command *global_service_event_handler_ptr; + +extern char *illegal_object_chars; + +extern int use_regexp_matches; +extern int use_true_regexp_matching; + +extern int use_syslog; +extern char *log_file; +extern char *log_archive_path; +extern int log_notifications; +extern int log_service_retries; +extern int log_host_retries; +extern int log_event_handlers; +extern int log_external_commands; +extern int log_passive_checks; +extern unsigned long logging_options; +extern unsigned long syslog_options; + +extern int service_check_timeout; +extern int service_check_timeout_state; +extern int host_check_timeout; +extern int event_handler_timeout; +extern int notification_timeout; + +extern int log_initial_states; +extern int log_current_states; + +extern int daemon_dumps_core; +extern int sig_id; +extern int caught_signal; + + +extern int verify_config; +extern int test_scheduling; +extern int precache_objects; +extern int use_precached_objects; + +extern int service_inter_check_delay_method; +extern int host_inter_check_delay_method; +extern int service_interleave_factor_method; +extern int max_host_check_spread; +extern int max_service_check_spread; + +extern sched_info scheduling_info; + +extern int max_parallel_service_checks; + +extern int check_reaper_interval; +extern int max_check_reaper_time; +extern int service_freshness_check_interval; +extern int host_freshness_check_interval; +extern int auto_rescheduling_interval; +extern int auto_rescheduling_window; + +extern int check_orphaned_services; +extern int check_orphaned_hosts; +extern int check_service_freshness; +extern int check_host_freshness; +extern int auto_reschedule_checks; + +extern int additional_freshness_latency; + +extern int check_for_updates; +extern int bare_update_check; +extern time_t last_update_check; +extern unsigned long update_uid; +extern int update_available; +extern char *last_program_version; +extern char *new_program_version; + +extern int use_aggressive_host_checking; +extern time_t cached_host_check_horizon; +extern time_t cached_service_check_horizon; +extern int enable_predictive_host_dependency_checks; +extern int enable_predictive_service_dependency_checks; + +extern int soft_state_dependencies; + +extern int retain_state_information; +extern int retention_update_interval; +extern int use_retained_program_state; +extern int use_retained_scheduling_info; +extern int retention_scheduling_horizon; +extern char *retention_file; +extern unsigned long retained_host_attribute_mask; +extern unsigned long retained_service_attribute_mask; +extern unsigned long retained_contact_host_attribute_mask; +extern unsigned long retained_contact_service_attribute_mask; +extern unsigned long retained_process_host_attribute_mask; +extern unsigned long retained_process_service_attribute_mask; + +extern int translate_passive_host_checks; +extern int passive_host_checks_are_soft; + +extern int status_update_interval; +extern char *retention_file; + +extern int time_change_threshold; + +extern unsigned long event_broker_options; + +extern double low_service_flap_threshold; +extern double high_service_flap_threshold; +extern double low_host_flap_threshold; +extern double high_host_flap_threshold; + +extern int use_large_installation_tweaks; +extern int enable_environment_macros; +extern int free_child_process_memory; +extern int child_processes_fork_twice; + +extern char *use_timezone; + +extern time_t max_check_result_file_age; + +extern char *debug_file; +extern int debug_level; +extern int debug_verbosity; +extern unsigned long max_debug_file_size; + +extern int allow_empty_hostgroup_assignment; + +extern time_t last_program_stop; +extern time_t event_start; + +extern int sigshutdown, sigrestart; +extern int currently_running_service_checks; +extern int currently_running_host_checks; + +extern unsigned long next_event_id; +extern unsigned long next_problem_id; +extern unsigned long next_comment_id; +extern unsigned long next_notification_id; + +extern unsigned long modified_process_attributes; +extern unsigned long modified_host_process_attributes; +extern unsigned long modified_service_process_attributes; + +extern squeue_t *nagios_squeue; +extern iobroker_set *nagios_iobs; + +extern struct check_stats check_statistics[MAX_CHECK_STATS_TYPES]; + +/*** perfdata variables ***/ +extern int perfdata_timeout; +extern char *host_perfdata_command; +extern char *service_perfdata_command; +extern char *host_perfdata_file_template; +extern char *service_perfdata_file_template; +extern char *host_perfdata_file; +extern char *service_perfdata_file; +extern int host_perfdata_file_append; +extern int service_perfdata_file_append; +extern int host_perfdata_file_pipe; +extern int service_perfdata_file_pipe; +extern unsigned long host_perfdata_file_processing_interval; +extern unsigned long service_perfdata_file_processing_interval; +extern char *host_perfdata_file_processing_command; +extern char *service_perfdata_file_processing_command; +extern int host_perfdata_process_empty_results; +extern int service_perfdata_process_empty_results; +/*** end perfdata variables */ + +extern struct notify_list *notification_list; + +extern struct check_engine nagios_check_engine; + +/* + * Everything we need to keep system load in check. + * Don't use this from modules. + */ +struct load_control { + time_t last_check; /* last time we checked the real load */ + time_t last_change; /* last time we changed settings */ + time_t check_interval; /* seconds between load checks */ + double load[3]; /* system load, as reported by getloadavg() */ + float backoff_limit; /* limit we must reach before we back off */ + float rampup_limit; /* limit we must reach before we ramp back up */ + unsigned int backoff_change; /* backoff by this much */ + unsigned int rampup_change; /* ramp up by this much */ + unsigned int changes; /* number of times we've changed settings */ + unsigned int jobs_max; /* upper setting for jobs_limit */ + unsigned int jobs_limit; /* current limit */ + unsigned int jobs_min; /* lower setting for jobs_limit */ + unsigned int jobs_running; /* jobs currently running */ + unsigned int nproc_limit; /* rlimit for user processes */ + unsigned int nofile_limit; /* rlimit for open files */ + unsigned int options; /* various option flags */ +}; +extern struct load_control loadctl; + +/* options for load control */ +#define LOADCTL_ENABLED (1 << 0) + + + /************* MISC LENGTH/SIZE DEFINITIONS ***********/ + + /* + NOTE: Plugin length is artificially capped at 8k to prevent runaway plugins from returning MBs/GBs of data + back to Nagios. If you increase the 8k cap by modifying this value, make sure you also increase the value + of MAX_EXTERNAL_COMMAND_LENGTH in common.h to allow for passive checks results received through the external + command file. EG 10/19/07 + */ +#define MAX_PLUGIN_OUTPUT_LENGTH 8192 /* max length of plugin output (including perf data) */ + + + /******************* STATE LOGGING TYPES **************/ + +#define INITIAL_STATES 1 +#define CURRENT_STATES 2 + + + + /************ SERVICE DEPENDENCY VALUES ***************/ + +#define DEPENDENCIES_OK 0 +#define DEPENDENCIES_FAILED 1 + + + + /*********** ROUTE CHECK PROPAGATION TYPES ************/ + +#define PROPAGATE_TO_PARENT_HOSTS 1 +#define PROPAGATE_TO_CHILD_HOSTS 2 + + + + /****************** FLAPPING TYPES ********************/ + +#define HOST_FLAPPING 0 +#define SERVICE_FLAPPING 1 + + + + /**************** NOTIFICATION TYPES ******************/ + +#define HOST_NOTIFICATION 0 +#define SERVICE_NOTIFICATION 1 + + + + /************* NOTIFICATION REASON TYPES ***************/ + +#define NOTIFICATION_NORMAL 0 +#define NOTIFICATION_ACKNOWLEDGEMENT 1 +#define NOTIFICATION_FLAPPINGSTART 2 +#define NOTIFICATION_FLAPPINGSTOP 3 +#define NOTIFICATION_FLAPPINGDISABLED 4 +#define NOTIFICATION_DOWNTIMESTART 5 +#define NOTIFICATION_DOWNTIMEEND 6 +#define NOTIFICATION_DOWNTIMECANCELLED 7 +#define NOTIFICATION_CUSTOM 8 + + + + /**************** EVENT HANDLER TYPES *****************/ + +#define HOST_EVENTHANDLER 0 +#define SERVICE_EVENTHANDLER 1 +#define GLOBAL_HOST_EVENTHANDLER 2 +#define GLOBAL_SERVICE_EVENTHANDLER 3 + + + + /***************** STATE CHANGE TYPES *****************/ + +#define HOST_STATECHANGE 0 +#define SERVICE_STATECHANGE 1 + + + + /***************** OBJECT CHECK TYPES *****************/ +#define SERVICE_CHECK 0 +#define HOST_CHECK 1 + + + + /******************* EVENT TYPES **********************/ + +#define EVENT_SERVICE_CHECK 0 /* active service check */ +#define EVENT_COMMAND_CHECK 1 /* external command check */ +#define EVENT_LOG_ROTATION 2 /* log file rotation */ +#define EVENT_PROGRAM_SHUTDOWN 3 /* program shutdown */ +#define EVENT_PROGRAM_RESTART 4 /* program restart */ +#define EVENT_CHECK_REAPER 5 /* reaps results from host and service checks */ +#define EVENT_ORPHAN_CHECK 6 /* checks for orphaned hosts and services */ +#define EVENT_RETENTION_SAVE 7 /* save (dump) retention data */ +#define EVENT_STATUS_SAVE 8 /* save (dump) status data */ +#define EVENT_SCHEDULED_DOWNTIME 9 /* scheduled host or service downtime */ +#define EVENT_SFRESHNESS_CHECK 10 /* checks service result "freshness" */ +#define EVENT_EXPIRE_DOWNTIME 11 /* checks for (and removes) expired scheduled downtime */ +#define EVENT_HOST_CHECK 12 /* active host check */ +#define EVENT_HFRESHNESS_CHECK 13 /* checks host result "freshness" */ +#define EVENT_RESCHEDULE_CHECKS 14 /* adjust scheduling of host and service checks */ +#define EVENT_EXPIRE_COMMENT 15 /* removes expired comments */ +#define EVENT_CHECK_PROGRAM_UPDATE 16 /* checks for new version of Nagios */ +#define EVENT_SLEEP 98 /* asynchronous sleep event that occurs when event queues are empty */ +#define EVENT_USER_FUNCTION 99 /* USER-defined function (modules) */ + +/* + * VERSIONFIX: Make EVENT_SLEEP and EVENT_USER_FUNCTION appear + * linearly in order. + */ + +#define EVENT_TYPE_STR(type) ( \ + type == EVENT_SERVICE_CHECK ? "SERVICE_CHECK" : \ + type == EVENT_COMMAND_CHECK ? "COMMAND_CHECK" : \ + type == EVENT_LOG_ROTATION ? "LOG_ROTATION" : \ + type == EVENT_PROGRAM_SHUTDOWN ? "PROGRAM_SHUTDOWN" : \ + type == EVENT_PROGRAM_RESTART ? "PROGRAM_RESTART" : \ + type == EVENT_CHECK_REAPER ? "CHECK_REAPER" : \ + type == EVENT_ORPHAN_CHECK ? "ORPHAN_CHECK" : \ + type == EVENT_RETENTION_SAVE ? "RETENTION_SAVE" : \ + type == EVENT_STATUS_SAVE ? "STATUS_SAVE" : \ + type == EVENT_SCHEDULED_DOWNTIME ? "SCHEDULED_DOWNTIME" : \ + type == EVENT_SFRESHNESS_CHECK ? "SFRESHNESS_CHECK" : \ + type == EVENT_EXPIRE_DOWNTIME ? "EXPIRE_DOWNTIME" : \ + type == EVENT_HOST_CHECK ? "HOST_CHECK" : \ + type == EVENT_HFRESHNESS_CHECK ? "HFRESHNESS_CHECK" : \ + type == EVENT_RESCHEDULE_CHECKS ? "RESCHEDULE_CHECKS" : \ + type == EVENT_EXPIRE_COMMENT ? "EXPIRE_COMMENT" : \ + type == EVENT_CHECK_PROGRAM_UPDATE ? "CHECK_PROGRAM_UPDATE" : \ + type == EVENT_SLEEP ? "SLEEP" : \ + type == EVENT_USER_FUNCTION ? "USER_FUNCTION" : \ + "UNKNOWN" \ +) + + + + /******* INTER-CHECK DELAY CALCULATION TYPES **********/ + +#define ICD_NONE 0 /* no inter-check delay */ +#define ICD_DUMB 1 /* dumb delay of 1 second */ +#define ICD_SMART 2 /* smart delay */ +#define ICD_USER 3 /* user-specified delay */ + + + + /******* INTERLEAVE FACTOR CALCULATION TYPES **********/ + +#define ILF_USER 0 /* user-specified interleave factor */ +#define ILF_SMART 1 /* smart interleave */ + + + + /************ SCHEDULED DOWNTIME TYPES ****************/ + +#define ACTIVE_DOWNTIME 0 /* active downtime - currently in effect */ +#define PENDING_DOWNTIME 1 /* pending downtime - scheduled for the future */ + + +NAGIOS_BEGIN_DECL + +/* useful for hosts and services to determine time 'til next check */ +#define normal_check_window(o) ((time_t)(o->check_interval * interval_length)) +#define retry_check_window(o) ((time_t)(o->retry_interval * interval_length)) +#define check_window(o) \ + ((!o->current_state && o->state_type == SOFT_STATE) ? \ + retry_check_window(o) : \ + normal_check_window(o)) + +/** Nerd subscription type */ +struct nerd_subscription { + int sd; + struct nerd_channel *chan; + char *format; /* requested format (macro string) for this subscription */ +}; + +/******************** FUNCTIONS **********************/ +extern int set_loadctl_options(char *opts, unsigned int len); + +/* silly helpers useful pretty much all over the place */ +extern const char *service_state_name(int state); +extern const char *host_state_name(int state); +extern const char *state_type_name(int state_type); +extern const char *check_type_name(int check_type); +extern const char *check_result_source(check_result *cr); + +/*** Nagios Event Radio Dispatcher functions ***/ +extern int nerd_init(void); +extern int nerd_mkchan(const char *name, const char *description, int (*handler)(int, void *), unsigned int callbacks); +extern int nerd_cancel_subscriber(int sd); +extern int nerd_get_channel_id(const char *chan_name); +extern objectlist *nerd_get_subscriptions(int chan_id); +extern int nerd_broadcast(unsigned int chan_id, void *buf, unsigned int len); + +/*** Query Handler functions, types and macros*/ +typedef int (*qh_handler)(int, char *, unsigned int); +extern int dump_event_stats(int sd); + +/* return codes for query_handlers() */ +#define QH_OK 0 /* keep listening */ +#define QH_CLOSE 1 /* we should close the socket */ +#define QH_INVALID 2 /* invalid query. Log and close */ +#define QH_TAKEOVER 3 /* handler will take full control. de-register but don't close */ +extern int qh_init(const char *path); +extern void qh_deinit(const char *path); +extern int qh_register_handler(const char *name, const char *description, unsigned int options, qh_handler handler); +extern const char *qh_strerror(int code); + +/**** Configuration Functions ****/ +int read_main_config_file(char *); /* reads the main config file (nagios.cfg) */ +int read_resource_file(char *); /* processes macros in resource file */ +int read_all_object_data(char *); /* reads all object config data */ + + +/**** Setup Functions ****/ +int pre_flight_check(void); /* try and verify the configuration data */ +int pre_flight_object_check(int *, int *); /* verify object relationships and settings */ +int pre_flight_circular_check(int *, int *); /* detects circular dependencies and paths */ +void init_timing_loop(void); /* setup the initial scheduling queue */ +void setup_sighandler(void); /* trap signals */ +void reset_sighandler(void); /* reset signals to default action */ +extern void handle_sigxfsz(int); /* handle SIGXFSZ */ + +int daemon_init(void); /* switches to daemon mode */ +int drop_privileges(char *, char *); /* drops privileges before startup */ +void display_scheduling_info(void); /* displays service check scheduling information */ + + +/**** Event Queue Functions ****/ +int init_event_queue(void); /* creates the queue nagios_squeue */ +timed_event *schedule_new_event(int, int, time_t, int, unsigned long, void *, int, void *, void *, int); /* schedules a new timed event */ +void reschedule_event(squeue_t *sq, timed_event *event); /* reschedules an event */ +void add_event(squeue_t *sq, timed_event *event); /* adds an event to the execution queue */ +void remove_event(squeue_t *sq, timed_event *event); /* remove an event from the execution queue */ +int event_execution_loop(void); /* main monitoring/event handler loop */ +int handle_timed_event(timed_event *); /* top level handler for timed events */ +void adjust_check_scheduling(void); /* auto-adjusts scheduling of host and service checks */ +void compensate_for_system_time_change(unsigned long, unsigned long); /* attempts to compensate for a change in the system time */ +void adjust_timestamp_for_time_change(time_t, time_t, unsigned long, time_t *); /* adjusts a timestamp variable for a system time change */ + + +/**** IPC Functions ****/ +int process_check_result_queue(char *); +int process_check_result_file(char *); +int process_check_result(check_result *); +int delete_check_result_file(char *); +int init_check_result(check_result *); +int free_check_result(check_result *); /* frees memory associated with a host/service check result */ +int parse_check_output(char *, char **, char **, char **, int, int); +int open_command_file(void); /* creates the external command file as a named pipe (FIFO) and opens it for reading */ +int close_command_file(void); /* closes and deletes the external command file (FIFO) */ + + +/**** Monitoring/Event Handler Functions ****/ +int check_service_dependencies(service *, int); /* checks service dependencies */ +int check_host_dependencies(host *, int); /* checks host dependencies */ +void check_for_orphaned_services(void); /* checks for orphaned services */ +void check_for_orphaned_hosts(void); /* checks for orphaned hosts */ +void check_service_result_freshness(void); /* checks the "freshness" of service check results */ +int is_service_result_fresh(service *, time_t, int); /* determines if a service's check results are fresh */ +void check_host_result_freshness(void); /* checks the "freshness" of host check results */ +int is_host_result_fresh(host *, time_t, int); /* determines if a host's check results are fresh */ +int my_system(char *, int, int *, double *, char **, int); /* executes a command via popen(), but also protects against timeouts */ +int my_system_r(nagios_macros *mac, char *, int, int *, double *, char **, int); /* thread-safe version of the above */ + + +/**** Flap Detection Functions ****/ +void check_for_service_flapping(service *, int, int); /* determines whether or not a service is "flapping" between states */ +void check_for_host_flapping(host *, int, int, int); /* determines whether or not a host is "flapping" between states */ +void set_service_flap(service *, double, double, double, int); /* handles a service that is flapping */ +void clear_service_flap(service *, double, double, double); /* handles a service that has stopped flapping */ +void set_host_flap(host *, double, double, double, int); /* handles a host that is flapping */ +void clear_host_flap(host *, double, double, double); /* handles a host that has stopped flapping */ +void enable_flap_detection_routines(void); /* enables flap detection on a program-wide basis */ +void disable_flap_detection_routines(void); /* disables flap detection on a program-wide basis */ +void enable_host_flap_detection(host *); /* enables flap detection for a particular host */ +void disable_host_flap_detection(host *); /* disables flap detection for a particular host */ +void enable_service_flap_detection(service *); /* enables flap detection for a particular service */ +void disable_service_flap_detection(service *); /* disables flap detection for a particular service */ +void handle_host_flap_detection_disabled(host *); /* handles the details when flap detection is disabled globally or on a per-host basis */ +void handle_service_flap_detection_disabled(service *); /* handles the details when flap detection is disabled globally or on a per-service basis */ + + +/**** Route/Host Check Functions ****/ +int check_host_check_viability(host *, int, int *, time_t *); +int adjust_host_check_attempt(host *, int); +int determine_host_reachability(host *); +int process_host_check_result(host *, int, char *, int, int, int, unsigned long); +int perform_on_demand_host_check(host *, int *, int, int, unsigned long); +int execute_sync_host_check(host *); +int run_scheduled_host_check(host *, int, double); +int run_async_host_check(host *, int, double, int, int, int *, time_t *); +int handle_async_host_check_result(host *, check_result *); + + +/**** Service Check Functions ****/ +int check_service_check_viability(service *, int, int *, time_t *); +int run_scheduled_service_check(service *, int, double); +int run_async_service_check(service *, int, double, int, int, int *, time_t *); +int handle_async_service_check_result(service *, check_result *); + + +/**** Event Handler Functions ****/ +int handle_host_state(host *); /* top level host state handler */ + + +/**** Common Check Fucntions *****/ +int reap_check_results(void); + + +/**** Check Statistics Functions ****/ +int init_check_stats(void); +int update_check_stats(int, time_t); +int generate_check_stats(void); + + +/**** Event Handler Functions ****/ +int obsessive_compulsive_service_check_processor(service *); /* distributed monitoring craziness... */ +int obsessive_compulsive_host_check_processor(host *); /* distributed monitoring craziness... */ +int handle_service_event(service *); /* top level service event logic */ +int run_service_event_handler(nagios_macros *mac, service *); /* runs the event handler for a specific service */ +int run_global_service_event_handler(nagios_macros *mac, service *); /* runs the global service event handler */ +int handle_host_event(host *); /* top level host event logic */ +int run_host_event_handler(nagios_macros *mac, host *); /* runs the event handler for a specific host */ +int run_global_host_event_handler(nagios_macros *mac, host *); /* runs the global host event handler */ + + +/**** Notification Functions ****/ +const char *notification_reason_name(unsigned int reason_type); +int check_service_notification_viability(service *, int, int); /* checks viability of notifying all contacts about a service */ +int is_valid_escalation_for_service_notification(service *, serviceescalation *, int); /* checks if an escalation entry is valid for a particular service notification */ +int should_service_notification_be_escalated(service *); /* checks if a service notification should be escalated */ +int service_notification(service *, int, char *, char *, int); /* notify all contacts about a service (problem or recovery) */ +int check_contact_service_notification_viability(contact *, service *, int, int); /* checks viability of notifying a contact about a service */ +int notify_contact_of_service(nagios_macros *mac, contact *, service *, int, char *, char *, int, int); /* notify a single contact about a service */ +int check_host_notification_viability(host *, int, int); /* checks viability of notifying all contacts about a host */ +int is_valid_escalation_for_host_notification(host *, hostescalation *, int); /* checks if an escalation entry is valid for a particular host notification */ +int should_host_notification_be_escalated(host *); /* checks if a host notification should be escalated */ +int host_notification(host *, int, char *, char *, int); /* notify all contacts about a host (problem or recovery) */ +int check_contact_host_notification_viability(contact *, host *, int, int); /* checks viability of notifying a contact about a host */ +int notify_contact_of_host(nagios_macros *mac, contact *, host *, int, char *, char *, int, int); /* notify a single contact about a host */ +int create_notification_list_from_host(nagios_macros *mac, host *,int,int *,int); /* given a host, create list of contacts to be notified (remove duplicates) */ +int create_notification_list_from_service(nagios_macros *mac, service *,int,int *,int); /* given a service, create list of contacts to be notified (remove duplicates) */ +int add_notification(nagios_macros *mac, contact *); /* adds a notification instance */ +notification *find_notification(contact *); /* finds a notification object */ +time_t get_next_host_notification_time(host *, time_t); /* calculates nex acceptable re-notification time for a host */ +time_t get_next_service_notification_time(service *, time_t); /* calculates nex acceptable re-notification time for a service */ + + +/**** Cleanup Functions ****/ +void cleanup(void); /* cleanup after ourselves (before quitting or restarting) */ +void free_memory(nagios_macros *mac); /* free memory allocated to all linked lists in memory */ +int reset_variables(void); /* reset all global variables */ +void free_notification_list(void); /* frees all memory allocated to the notification list */ + + +/**** Miscellaneous Functions ****/ +void sighandler(int); /* handles signals */ +void my_system_sighandler(int); /* handles timeouts when executing commands via my_system() */ +char *get_next_string_from_buf(char *buf, int *start_index, int bufsize); +int compare_strings(char *, char *); /* compares two strings for equality */ +char *escape_newlines(char *); +int contains_illegal_object_chars(char *); /* tests whether or not an object name (host, service, etc.) contains illegal characters */ +int my_rename(char *, char *); /* renames a file - works across filesystems */ +int my_fcopy(char *, char *); /* copies a file - works across filesystems */ +int my_fdcopy(char *, char *, int); /* copies a named source to an already opened destination file */ + +/* thread-safe version of get_raw_command_line_r() */ +extern int get_raw_command_line_r(nagios_macros *mac, command *, char *, char **, int); + +/* + * given a raw command line, determine the actual command to run + * Manipulates global_macros.argv and is thus not threadsafe + */ +extern int get_raw_command_line(command *, char *, char **, int); + +int check_time_against_period(time_t, timeperiod *); /* check to see if a specific time is covered by a time period */ +int is_daterange_single_day(daterange *); +time_t calculate_time_from_weekday_of_month(int, int, int, int); /* calculates midnight time of specific (3rd, last, etc.) weekday of a particular month */ +time_t calculate_time_from_day_of_month(int, int, int); /* calculates midnight time of specific (1st, last, etc.) day of a particular month */ +void get_next_valid_time(time_t, time_t *, timeperiod *); /* get the next valid time in a time period */ +time_t get_next_log_rotation_time(void); /* determine the next time to schedule a log rotation */ +int dbuf_init(dbuf *, int); +int dbuf_free(dbuf *); +int dbuf_strcat(dbuf *, const char *); +int set_environment_var(char *, char *, int); /* sets/clears and environment variable */ +int check_for_nagios_updates(int, int); /* checks to see if new version of Nagios are available */ +int query_update_api(void); /* checks to see if new version of Nagios are available */ + + +/**** External Command Functions ****/ +int process_external_command1(char *); /* top-level external command processor */ +int process_external_command2(int, time_t, char *); /* process an external command */ +int process_external_commands_from_file(char *, int); /* process external commands in a file */ +int process_host_command(int, time_t, char *); /* process an external host command */ +int process_hostgroup_command(int, time_t, char *); /* process an external hostgroup command */ +int process_service_command(int, time_t, char *); /* process an external service command */ +int process_servicegroup_command(int, time_t, char *); /* process an external servicegroup command */ +int process_contact_command(int, time_t, char *); /* process an external contact command */ +int process_contactgroup_command(int, time_t, char *); /* process an external contactgroup command */ + + +/**** External Command Implementations ****/ +int cmd_add_comment(int, time_t, char *); /* add a service or host comment */ +int cmd_delete_comment(int, char *); /* delete a service or host comment */ +int cmd_delete_all_comments(int, char *); /* delete all comments associated with a host or service */ +int cmd_delay_notification(int, char *); /* delay a service or host notification */ +int cmd_schedule_check(int, char *); /* schedule an immediate or delayed host check */ +int cmd_schedule_host_service_checks(int, char *, int); /* schedule an immediate or delayed checks of all services on a host */ +int cmd_signal_process(int, char *); /* schedules a program shutdown or restart */ +int cmd_process_service_check_result(int, time_t, char *); /* processes a passive service check */ +int cmd_process_host_check_result(int, time_t, char *); /* processes a passive host check */ +int cmd_acknowledge_problem(int, char *); /* acknowledges a host or service problem */ +int cmd_remove_acknowledgement(int, char *); /* removes a host or service acknowledgement */ +int cmd_schedule_downtime(int, time_t, char *); /* schedules host or service downtime */ +int cmd_delete_downtime(int, char *); /* cancels active/pending host or service scheduled downtime */ +int cmd_change_object_int_var(int, char *); /* changes host/svc (int) variable */ +int cmd_change_object_char_var(int, char *); /* changes host/svc (char) variable */ +int cmd_change_object_custom_var(int, char *); /* changes host/svc custom variable */ +int cmd_process_external_commands_from_file(int, char *); /* process external commands from a file */ +int cmd_delete_downtime_by_start_time_comment(int, char *); +int cmd_delete_downtime_by_host_name(int, char *); +int cmd_delete_downtime_by_hostgroup_name(int, char *); + +int process_passive_service_check(time_t, char *, char *, int, char *); +int process_passive_host_check(time_t, char *, int, char *); + + +/**** Internal Command Implementations ****/ +void disable_service_checks(service *); /* disables a service check */ +void enable_service_checks(service *); /* enables a service check */ +void schedule_service_check(service *, time_t, int); /* schedules an immediate or delayed service check */ +void schedule_host_check(host *, time_t, int); /* schedules an immediate or delayed host check */ +void enable_all_notifications(void); /* enables notifications on a program-wide basis */ +void disable_all_notifications(void); /* disables notifications on a program-wide basis */ +void enable_service_notifications(service *); /* enables service notifications */ +void disable_service_notifications(service *); /* disables service notifications */ +void enable_host_notifications(host *); /* enables host notifications */ +void disable_host_notifications(host *); /* disables host notifications */ +void enable_and_propagate_notifications(host *, int, int, int, int); /* enables notifications for all hosts and services beyond a given host */ +void disable_and_propagate_notifications(host *, int, int, int, int); /* disables notifications for all hosts and services beyond a given host */ +void schedule_and_propagate_downtime(host *, time_t, char *, char *, time_t, time_t, int, unsigned long, unsigned long); /* schedules downtime for all hosts beyond a given host */ +void acknowledge_host_problem(host *, char *, char *, int, int, int); /* acknowledges a host problem */ +void acknowledge_service_problem(service *, char *, char *, int, int, int); /* acknowledges a service problem */ +void remove_host_acknowledgement(host *); /* removes a host acknowledgement */ +void remove_service_acknowledgement(service *); /* removes a service acknowledgement */ +void start_executing_service_checks(void); /* starts executing service checks */ +void stop_executing_service_checks(void); /* stops executing service checks */ +void start_accepting_passive_service_checks(void); /* starts accepting passive service check results */ +void stop_accepting_passive_service_checks(void); /* stops accepting passive service check results */ +void enable_passive_service_checks(service *); /* enables passive service checks for a particular service */ +void disable_passive_service_checks(service *); /* disables passive service checks for a particular service */ +void start_using_event_handlers(void); /* enables event handlers on a program-wide basis */ +void stop_using_event_handlers(void); /* disables event handlers on a program-wide basis */ +void enable_service_event_handler(service *); /* enables the event handler for a particular service */ +void disable_service_event_handler(service *); /* disables the event handler for a particular service */ +void enable_host_event_handler(host *); /* enables the event handler for a particular host */ +void disable_host_event_handler(host *); /* disables the event handler for a particular host */ +void enable_host_checks(host *); /* enables checks of a particular host */ +void disable_host_checks(host *); /* disables checks of a particular host */ +void start_obsessing_over_service_checks(void); /* start obsessing about service check results */ +void stop_obsessing_over_service_checks(void); /* stop obsessing about service check results */ +void start_obsessing_over_host_checks(void); /* start obsessing about host check results */ +void stop_obsessing_over_host_checks(void); /* stop obsessing about host check results */ +void enable_service_freshness_checks(void); /* enable service freshness checks */ +void disable_service_freshness_checks(void); /* disable service freshness checks */ +void enable_host_freshness_checks(void); /* enable host freshness checks */ +void disable_host_freshness_checks(void); /* disable host freshness checks */ +void enable_performance_data(void); /* enables processing of performance data on a program-wide basis */ +void disable_performance_data(void); /* disables processing of performance data on a program-wide basis */ +void start_executing_host_checks(void); /* starts executing host checks */ +void stop_executing_host_checks(void); /* stops executing host checks */ +void start_accepting_passive_host_checks(void); /* starts accepting passive host check results */ +void stop_accepting_passive_host_checks(void); /* stops accepting passive host check results */ +void enable_passive_host_checks(host *); /* enables passive host checks for a particular host */ +void disable_passive_host_checks(host *); /* disables passive host checks for a particular host */ +void start_obsessing_over_service(service *); /* start obsessing about specific service check results */ +void stop_obsessing_over_service(service *); /* stop obsessing about specific service check results */ +void start_obsessing_over_host(host *); /* start obsessing about specific host check results */ +void stop_obsessing_over_host(host *); /* stop obsessing about specific host check results */ +void set_host_notification_number(host *, int); /* sets current notification number for a specific host */ +void set_service_notification_number(service *, int); /* sets current notification number for a specific service */ +void enable_contact_host_notifications(contact *); /* enables host notifications for a specific contact */ +void disable_contact_host_notifications(contact *); /* disables host notifications for a specific contact */ +void enable_contact_service_notifications(contact *); /* enables service notifications for a specific contact */ +void disable_contact_service_notifications(contact *); /* disables service notifications for a specific contact */ + +int launch_command_file_worker(void); +int shutdown_command_file_worker(void); + +char *get_program_version(void); +char *get_program_modification_date(void); + +NAGIOS_END_DECL +#endif + diff --git a/nagios4/nebcallbacks.h b/nagios4/nebcallbacks.h new file mode 100644 index 0000000..9360fb6 --- /dev/null +++ b/nagios4/nebcallbacks.h @@ -0,0 +1,70 @@ +/***************************************************************************** + * + * NEBCALLBACKS.H - Include file for event broker modules + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBCALLBACKS_H +#define _NEBCALLBACKS_H + +#include "nebmodules.h" + + +/***** CALLBACK TYPES *****/ + +#define NEBCALLBACK_NUMITEMS 26 /* total number of callback types we have */ + +#define NEBCALLBACK_PROCESS_DATA 0 +#define NEBCALLBACK_TIMED_EVENT_DATA 1 +#define NEBCALLBACK_LOG_DATA 2 +#define NEBCALLBACK_SYSTEM_COMMAND_DATA 3 +#define NEBCALLBACK_EVENT_HANDLER_DATA 4 +#define NEBCALLBACK_NOTIFICATION_DATA 5 +#define NEBCALLBACK_SERVICE_CHECK_DATA 6 +#define NEBCALLBACK_HOST_CHECK_DATA 7 +#define NEBCALLBACK_COMMENT_DATA 8 +#define NEBCALLBACK_DOWNTIME_DATA 9 +#define NEBCALLBACK_FLAPPING_DATA 10 +#define NEBCALLBACK_PROGRAM_STATUS_DATA 11 +#define NEBCALLBACK_HOST_STATUS_DATA 12 +#define NEBCALLBACK_SERVICE_STATUS_DATA 13 +#define NEBCALLBACK_ADAPTIVE_PROGRAM_DATA 14 +#define NEBCALLBACK_ADAPTIVE_HOST_DATA 15 +#define NEBCALLBACK_ADAPTIVE_SERVICE_DATA 16 +#define NEBCALLBACK_EXTERNAL_COMMAND_DATA 17 +#define NEBCALLBACK_AGGREGATED_STATUS_DATA 18 +#define NEBCALLBACK_RETENTION_DATA 19 +#define NEBCALLBACK_CONTACT_NOTIFICATION_DATA 20 +#define NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA 21 +#define NEBCALLBACK_ACKNOWLEDGEMENT_DATA 22 +#define NEBCALLBACK_STATE_CHANGE_DATA 23 +#define NEBCALLBACK_CONTACT_STATUS_DATA 24 +#define NEBCALLBACK_ADAPTIVE_CONTACT_DATA 25 + +#define nebcallback_flag(x) (1 << (x)) + +/***** CALLBACK FUNCTIONS *****/ +NAGIOS_BEGIN_DECL + +int neb_register_callback(int callback_type, void *mod_handle, int priority, int (*callback_func)(int, void *)); +int neb_deregister_callback(int callback_type, int (*callback_func)(int, void *)); +int neb_deregister_module_callbacks(nebmodule *); + +NAGIOS_END_DECL +#endif diff --git a/nagios4/neberrors.h b/nagios4/neberrors.h new file mode 100644 index 0000000..bd876a6 --- /dev/null +++ b/nagios4/neberrors.h @@ -0,0 +1,67 @@ +/***************************************************************************** + * + * NEBERRORS.H - Event broker errors + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBERRORS_H +#define _NEBERRORS_H + + +/***** GENERIC DEFINES *****/ + +#define NEB_OK 0 +#define NEB_ERROR -1 + +#define NEB_TRUE 1 +#define NEB_FALSE 0 + + + +/***** GENERIC ERRORS *****/ + +#define NEBERROR_NOMEM 100 /* memory could not be allocated */ + + + +/***** CALLBACK ERRORS *****/ + +#define NEBERROR_NOCALLBACKFUNC 200 /* no callback function was specified */ +#define NEBERROR_NOCALLBACKLIST 201 /* callback list not initialized */ +#define NEBERROR_CALLBACKBOUNDS 202 /* callback type was out of bounds */ +#define NEBERROR_CALLBACKNOTFOUND 203 /* the callback could not be found */ +#define NEBERROR_NOMODULEHANDLE 204 /* no module handle specified */ +#define NEBERROR_BADMODULEHANDLE 205 /* bad module handle */ +#define NEBERROR_CALLBACKOVERRIDE 206 /* module wants to override default Nagios handling of event */ +#define NEBERROR_CALLBACKCANCEL 207 /* module wants to cancel callbacks to other modules */ + + + +/***** MODULE ERRORS *****/ + +#define NEBERROR_NOMODULE 300 /* no module was specified */ + + + +/***** MODULE INFO ERRORS *****/ + +#define NEBERROR_MODINFOBOUNDS 400 /* module info index was out of bounds */ + + +#endif diff --git a/nagios4/nebmods.h b/nagios4/nebmods.h new file mode 100644 index 0000000..3f69167 --- /dev/null +++ b/nagios4/nebmods.h @@ -0,0 +1,62 @@ +/***************************************************************************** + * + * NEBMODS.H - Include file for event broker modules + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBMODS_H +#define _NEBMODS_H + +#include "nebcallbacks.h" +#include "nebmodules.h" + +NAGIOS_BEGIN_DECL + +/***** MODULE STRUCTURES *****/ + +/* NEB module callback list struct */ +typedef struct nebcallback_struct { + void *callback_func; + void *module_handle; + int priority; + struct nebcallback_struct *next; + } nebcallback; + + + +/***** MODULE FUNCTIONS *****/ + +int neb_init_modules(void); +int neb_deinit_modules(void); +int neb_load_all_modules(void); +int neb_load_module(nebmodule *); +int neb_free_module_list(void); +int neb_unload_all_modules(int, int); +int neb_unload_module(nebmodule *, int, int); +int neb_add_module(char *, char *, int); +int neb_add_core_module(nebmodule *mod); + + +/***** CALLBACK FUNCTIONS *****/ +int neb_init_callback_list(void); +int neb_free_callback_list(void); +int neb_make_callbacks(int, void *); + +NAGIOS_END_DECL +#endif diff --git a/nagios4/nebmodules.h b/nagios4/nebmodules.h new file mode 100644 index 0000000..259ed5c --- /dev/null +++ b/nagios4/nebmodules.h @@ -0,0 +1,94 @@ +/***************************************************************************** + * + * NEBMODULES.H - Include file for event broker modules + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBMODULES_H +#define _NEBMODULES_H + +#include "common.h" +NAGIOS_BEGIN_DECL + + /***** MODULE VERSION INFORMATION *****/ + +#define NEB_API_VERSION(x) int __neb_api_version = x; +#define CURRENT_NEB_API_VERSION 4 + + + + /***** MODULE INFORMATION *****/ + +#define NEBMODULE_MODINFO_NUMITEMS 6 +#define NEBMODULE_MODINFO_TITLE 0 +#define NEBMODULE_MODINFO_AUTHOR 1 +#define NEBMODULE_MODINFO_COPYRIGHT 2 +#define NEBMODULE_MODINFO_VERSION 3 +#define NEBMODULE_MODINFO_LICENSE 4 +#define NEBMODULE_MODINFO_DESC 5 + + + + /***** MODULE LOAD/UNLOAD OPTIONS *****/ + +#define NEBMODULE_NORMAL_LOAD 0 /* module is being loaded normally */ +#define NEBMODULE_REQUEST_UNLOAD 0 /* request module to unload (but don't force it) */ +#define NEBMODULE_FORCE_UNLOAD 1 /* force module to unload */ + + + + /***** MODULES UNLOAD REASONS *****/ + +#define NEBMODULE_NEB_SHUTDOWN 1 /* event broker is shutting down */ +#define NEBMODULE_NEB_RESTART 2 /* event broker is restarting */ +#define NEBMODULE_ERROR_NO_INIT 3 /* _module_init() function was not found in module */ +#define NEBMODULE_ERROR_BAD_INIT 4 /* _module_init() function returned a bad code */ +#define NEBMODULE_ERROR_API_VERSION 5 /* module version is incompatible with current api */ + + + +/***** MODULE STRUCTURES *****/ + +/* NEB module structure */ +typedef struct nebmodule_struct { + char *filename; + char *dl_file; /* the file we actually loaded */ + char *args; + char *info[NEBMODULE_MODINFO_NUMITEMS]; + int should_be_loaded; + int is_currently_loaded; + int core_module; +#ifdef USE_LTDL + lt_dlhandle module_handle; + lt_ptr init_func; + lt_ptr deinit_func; +#else + void *module_handle; + void *init_func; + void *deinit_func; +#endif + struct nebmodule_struct *next; + } nebmodule; + + +/***** MODULE FUNCTIONS *****/ +int neb_set_module_info(void *, int, char *); + +NAGIOS_END_DECL +#endif diff --git a/nagios4/nebstructs.h b/nagios4/nebstructs.h new file mode 100644 index 0000000..e598bc7 --- /dev/null +++ b/nagios4/nebstructs.h @@ -0,0 +1,525 @@ +/***************************************************************************** + * + * NEBSTRUCTS.H - Event broker includes for Nagios + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBSTRUCTS_H +#define _NEBSTRUCTS_H + +#include "common.h" +#include "objects.h" +#include "nagios.h" + +NAGIOS_BEGIN_DECL + +/****** STRUCTURES *************************/ + +/* process data structure */ +typedef struct nebstruct_process_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + } nebstruct_process_data; + + +/* timed event data structure */ +typedef struct nebstruct_timed_event_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int event_type; + int recurring; + time_t run_time; + void *event_data; + + void *event_ptr; + } nebstruct_timed_event_data; + + +/* log data structure */ +typedef struct nebstruct_log_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t entry_time; + int data_type; + char *data; + } nebstruct_log_data; + + +/* system command structure */ +typedef struct nebstruct_system_command_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + struct timeval start_time; + struct timeval end_time; + int timeout; + char *command_line; + int early_timeout; + double execution_time; + int return_code; + char *output; + } nebstruct_system_command_data; + + +/* event handler structure */ +typedef struct nebstruct_event_handler_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int eventhandler_type; + char *host_name; + char *service_description; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + int return_code; + char *output; + + void *object_ptr; + } nebstruct_event_handler_data; + + +/* host check structure */ +typedef struct nebstruct_host_check_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + int current_attempt; + int check_type; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + check_result *check_result_ptr; + + void *object_ptr; + } nebstruct_host_check_data; + + +/* service check structure */ +typedef struct nebstruct_service_check_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + char *service_description; + int check_type; + int current_attempt; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + check_result *check_result_ptr; + + void *object_ptr; + } nebstruct_service_check_data; + + +/* comment data structure */ +typedef struct nebstruct_comment_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int comment_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + int persistent; + int source; + int entry_type; + int expires; + time_t expire_time; + unsigned long comment_id; + + void *object_ptr; /* not implemented yet */ + } nebstruct_comment_data; + + +/* downtime data structure */ +typedef struct nebstruct_downtime_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int downtime_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + time_t start_time; + time_t end_time; + int fixed; + unsigned long duration; + unsigned long triggered_by; + unsigned long downtime_id; + + void *object_ptr; /* not implemented yet */ + } nebstruct_downtime_data; + + +/* flapping data structure */ +typedef struct nebstruct_flapping_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int flapping_type; + char *host_name; + char *service_description; + double percent_change; + double high_threshold; + double low_threshold; + unsigned long comment_id; + + void *object_ptr; + } nebstruct_flapping_data; + + +/* program status structure */ +typedef struct nebstruct_program_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t program_start; + int pid; + int daemon_mode; + time_t last_log_rotation; + int notifications_enabled; + int active_service_checks_enabled; + int passive_service_checks_enabled; + int active_host_checks_enabled; + int passive_host_checks_enabled; + int event_handlers_enabled; + int flap_detection_enabled; + int process_performance_data; + int obsess_over_hosts; + int obsess_over_services; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; + char *global_host_event_handler; + char *global_service_event_handler; + } nebstruct_program_status_data; + + +/* host status structure */ +typedef struct nebstruct_host_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + } nebstruct_host_status_data; + + +/* service status structure */ +typedef struct nebstruct_service_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + } nebstruct_service_status_data; + + +/* contact status structure */ +typedef struct nebstruct_contact_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + } nebstruct_contact_status_data; + + +/* notification data structure */ +typedef struct nebstruct_notification_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + int contacts_notified; + + void *object_ptr; + } nebstruct_notification_data; + + +/* contact notification data structure */ +typedef struct nebstruct_contact_notification_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + } nebstruct_contact_notification_data; + + +/* contact notification method data structure */ +typedef struct nebstruct_contact_notification_method_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + char *command_name; + char *command_args; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + } nebstruct_contact_notification_method_data; + + +/* adaptive program data structure */ +typedef struct nebstruct_adaptive_program_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + } nebstruct_adaptive_program_data; + + +/* adaptive host data structure */ +typedef struct nebstruct_adaptive_host_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + } nebstruct_adaptive_host_data; + + +/* adaptive service data structure */ +typedef struct nebstruct_adaptive_service_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + } nebstruct_adaptive_service_data; + + +/* adaptive contact data structure */ +typedef struct nebstruct_adaptive_contact_data_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + + void *object_ptr; + } nebstruct_adaptive_contact_data; + + +/* external command data structure */ +typedef struct nebstruct_external_command_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + time_t entry_time; + char *command_string; + char *command_args; + } nebstruct_external_command_data; + + +/* aggregated status data structure */ +typedef struct nebstruct_aggregated_status_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + } nebstruct_aggregated_status_data; + + +/* retention data structure */ +typedef struct nebstruct_retention_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + } nebstruct_retention_data; + + +/* acknowledgement structure */ +typedef struct nebstruct_acknowledgement_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int acknowledgement_type; + char *host_name; + char *service_description; + int state; + char *author_name; + char *comment_data; + int is_sticky; + int persistent_comment; + int notify_contacts; + + void *object_ptr; + } nebstruct_acknowledgement_data; + + +/* state change structure */ +typedef struct nebstruct_statechange_struct { + int type; + int flags; + int attr; + struct timeval timestamp; + + int statechange_type; + char *host_name; + char *service_description; + int state; + int state_type; + int current_attempt; + int max_attempts; + char *output; + + void *object_ptr; + } nebstruct_statechange_data; + +NAGIOS_END_DECL +#endif diff --git a/nagios4/nsock.h b/nagios4/nsock.h new file mode 100644 index 0000000..115ae56 --- /dev/null +++ b/nagios4/nsock.h @@ -0,0 +1,76 @@ +#ifndef LIBNAGIOS_nsock_h__ +#define LIBNAGIOS_nsock_h__ +#include + +/** + * @file nsock.h + * @brief Nagios socket helper library + * + * This is a pretty stupid library, but since so many addons and + * now Nagios core itself makes use of sockets, we might as well + * have some simple wrappers for it that handle the most common + * cases. + * + * @{ + */ + +#define NSOCK_EBIND (-1) /**< failed to bind() */ +#define NSOCK_ELISTEN (-2) /**< failed to listen() */ +#define NSOCK_ESOCKET (-3) /**< failed to socket() */ +#define NSOCK_EUNLINK (-4) /**< failed to unlink() */ +#define NSOCK_ECONNECT (-5) /**< failed to connect() */ +#define NSOCK_EFCNTL (-6) /**< failed to fcntl() */ +#define NSOCK_EINVAL (-EINVAL) /**< -22, normally */ + +/* flags for the various create calls */ +#define NSOCK_TCP (1 << 0) /**< use tcp mode */ +#define NSOCK_UDP (1 << 1) /**< use udp mode */ +#define NSOCK_UNLINK (1 << 2) /**< unlink existing path (only nsock_unix) */ +#define NSOCK_REUSE (1 << 2) /**< reuse existing address */ +#define NSOCK_CONNECT (1 << 3) /**< connect rather than create */ +#define NSOCK_BLOCK (1 << 4) /**< socket should be in blocking mode */ + +/** + * Grab an error string relating to nsock_unix() + * @param code The error code return by the nsock library + * @return An error string describing the error + */ +extern const char *nsock_strerror(int code); + +/** + * Create or connect to a unix socket + * To control permissions on sockets when NSOCK_LISTEN is specified, + * callers will have to modify their umask() before (and possibly + * after) the nsock_unix() call. + * + * @param path The path to connect to or create + * @param flags Various options controlling the mode of the socket + * @return An NSOCK_E macro on errors, the created socket on succes + */ +extern int nsock_unix(const char *path, unsigned int flags); + +/** + * Write a nul-terminated message to the socket pointed to by sd. + * This isn't quite the same as dprintf(), which doesn't include + * the terminating nul byte. + * @note This function may block, so poll(2) for writability + * @param sd The socket to write to + * @param fmt The format string + * @return Whatever write() returns + */ +extern int nsock_printf_nul(int sd, const char *fmt, ...) + __attribute__((__format__(__printf__, 2, 3))); + +/** + * Write a printf()-formatted string to the socket pointed to by sd. + * This is identical to dprintf(), which is unfortunately GNU only. + * @note This function may block, so poll(2) for writability + * @param sd The socket to write to + * @param fmt The format string + * @return Whatever write() returns + */ +extern int nsock_printf(int sd, const char *fmt, ...) + __attribute__((__format__(__printf__, 2, 3))); + +/** @} */ +#endif /* LIBNAGIOS_nsock_h__ */ diff --git a/nagios4/nspath.h b/nagios4/nspath.h new file mode 100644 index 0000000..7c5fd54 --- /dev/null +++ b/nagios4/nspath.h @@ -0,0 +1,91 @@ +#ifndef LIBNAGIOS_nspath_h__ +#define LIBNAGIOS_nspath_h__ +#ifndef _GNU_SOURCE +# ifndef NODOXY +# define _GNU_SOURCE 1 +# endif +#endif +#include +#include +#include "snprintf.h" + +/** + * @file nspath.h + * @brief path handling functions + * + * This library handles path normalization and resolution. It's nifty + * if you want to turn relative paths into absolute ones, or if you + * want to make insane ones sane, but without chdir()'ing your way + * around the filesystem. + * + * @{ + */ + +/** + * Normalize a path + * By "normalize", we mean that we convert dot-slash and dot-dot-slash + * embedded components into a legible continuous string of characters. + * Leading and trailing slashes are kept exactly as they are in input, + * but with sequences of slashes reduced to a single one. + * + * "foo/bar/.././lala.txt" becomes "foo/lala.txt" + * "../../../../bar/../foo/" becomes "/foo/" + * "////foo////././bar" becomes "/foo/bar" + * @param orig_path The path to normalize + * @return A newly allocated string containing the normalized path + */ +extern char *nspath_normalize(const char *orig_path); + +/** + * Make the "base"-relative path "rel_path" absolute. + * Turns the relative path "rel_path" into an absolute path and + * resolves it as if we were currently in "base". If "base" is + * NULL, the current working directory is used. If "base" is not + * null, it should be an absolute path for the result to make + * sense. + * + * @param rel_path The relative path to convert + * @param base The base directory (if NULL, we use current working dir) + * @return A newly allocated string containing the absolute path + */ +extern char *nspath_absolute(const char *rel_path, const char *base); + +/** + * Canonicalize the "base"-relative path "rel_path". + * errno gets properly set in case of errors. + * @param rel_path The path to transform + * @param base The base we should operate relative to + * @return Newly allocated canonical path on succes, NULL on errors + */ +extern char *nspath_real(const char *rel_path, const char *base); + +/** + * Get absolute dirname of "path", relative to "base" + * @param path Full path to target object (file or subdir) + * @param base The base directory (if NULL, we use current working dir) + * @return NULL on errors, allocated absolute directory name on success + */ +extern char *nspath_absolute_dirname(const char *path, const char *base); + + +/** + * Recursively create a directory, just like mkdir_p would. + * @note This function *will* taint errno with ENOENT if any path + * component has to be created. + * @note If "path" has a trailing slash, NSPATH_MKDIR_SKIP_LAST + * won't have any effect. That's considered a feature, since the + * option is designed so one can send a file-path to the function + * and have it create the directory structure for it. + * @param path Path to create, in normalized form + * @param mode Filemode (same as mkdir() takes) + * @param options Options flag. See NSPATH_MKDIR_* for or-able options + * @return 0 on success, -1 on errors and errno will hold error code + * from either stat() or mkdir(). + */ +extern int nspath_mkdir_p(const char *path, mode_t mode, int options); + +/** Don't mkdir() last element of path when calling nspath_mkdir_p() */ +#define NSPATH_MKDIR_SKIP_LAST (1 << 0) + +/** @} */ +#endif diff --git a/nagios4/nsutils.h b/nagios4/nsutils.h new file mode 100644 index 0000000..0ee1573 --- /dev/null +++ b/nagios4/nsutils.h @@ -0,0 +1,111 @@ +#ifndef LIBNAGIOS_nsutils_h__ +#define LIBNAGIOS_nsutils_h__ +#include + +/** + * @file nsutils.h + * @brief Non-Standard (or Nagios) utility functions and macros. + * + * This is where we house all helpers and macros that fall outside + * the "standard-ish" norm. The prefixes "nsu_" and NSU_ are + * reserved for this purpose, so we avoid clashing with other + * applications that may have similarly-acting functions with + * identical names. + * + * The functions already here lack the nsu_ prefix for backwards + * compatibility reasons. It's possible we'll have to fix that + * some day, but let's leave that for later. + * + * @{ + */ + +/** Macro for dynamically increasing vector lengths */ +#define alloc_nr(x) (((x)+16)*3/2) + +/** + * Check if a number is a power of 2 + * @param x The number to check + * @return 1 if the number is a power of 2, 0 if it's not + */ +static inline int nsu_ispow2(unsigned int x) +{ + return x > 1 ? !(x & (x - 1)) : 0; +} + +/** + * Round up to a power of 2 + * Yes, this is the most cryptic function name in all of Nagios, but I + * like it, so shush. + * @param r The number to round up + * @return r, rounded up to the nearest power of 2. + */ +static inline unsigned int rup2pof2(unsigned int r) +{ + r--; + if (!r) + return 2; + r |= r >> 1; + r |= r >> 2; + r |= r >> 4; + r |= r >> 8; + r |= r >> 16; + + return r + 1; +} + +/** + * Grab a random unsigned int in the range between low and high. + * Note that the PRNG has to be seeded prior to calling this. + * @param low The lower bound, inclusive + * @param high The higher bound, inclusive + * @return An unsigned integer in the mathematical range [low, high] + */ +static inline unsigned int ranged_urand(unsigned int low, unsigned int high) +{ + return low + (rand() * (1.0 / (RAND_MAX + 1.0)) * (high - low)); +} + +/** + * Get number of online cpus + * @return Active cpu cores detected on success. 0 on failure. + */ +extern int real_online_cpus(void); + +/** + * Wrapper for real_online_cpus(), returning 1 in case we can't + * detect any active cpus. + * @return Number of active cpu cores on success. 1 on failure. + */ +extern int online_cpus(void); + +/** + * Create a short-lived string in stack-allocated memory + * The number and size of strings is limited (currently to 256 strings of + * 32 bytes each), so beware and use this sensibly. Intended for + * number-to-string conversion and other short strings. + * @note The returned string must *not* be free()'d! + * @param[in] fmt The format string + * @return A pointer to the formatted string on success. Undefined on errors + */ +extern const char *mkstr(const char *fmt, ...) + __attribute__((__format__(__printf__, 1, 2))); + +/** + * Calculate the millisecond delta between two timeval structs + * @param[in] start The start time + * @param[in] stop The stop time + * @return The millisecond delta between the two structs + */ +extern int tv_delta_msec(const struct timeval *start, const struct timeval *stop); + + +/** + * Get timeval delta as seconds + * @param start The start time + * @param stop The stop time + * @return time difference in fractions of seconds + */ +extern float tv_delta_f(const struct timeval *start, const struct timeval *stop); + +/** @} */ +#endif /* LIBNAGIOS_nsutils_h__ */ diff --git a/nagios4/objects.h b/nagios4/objects.h new file mode 100644 index 0000000..0ea7634 --- /dev/null +++ b/nagios4/objects.h @@ -0,0 +1,853 @@ +/***************************************************************************** + * + * OBJECTS.H - Header file for object addition/search functions + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _OBJECTS_H +#define _OBJECTS_H + +#include "common.h" + +NAGIOS_BEGIN_DECL + + +/*************** CURRENT OBJECT REVISION **************/ + +#define CURRENT_OBJECT_STRUCTURE_VERSION 402 /* increment when changes are made to data structures... */ +/* Nagios 3 starts at 300, Nagios 4 at 400, etc. */ + + + +/***************** OBJECT SIZE LIMITS *****************/ + +#define MAX_STATE_HISTORY_ENTRIES 21 /* max number of old states to keep track of for flap detection */ +#define MAX_CONTACT_ADDRESSES 6 /* max number of custom addresses a contact can have */ + + + +/***************** SKIP LISTS ****************/ + +#define NUM_OBJECT_SKIPLISTS 12 +#define NUM_HASHED_OBJECT_TYPES 8 + +#define HOST_SKIPLIST 0 +#define SERVICE_SKIPLIST 1 +#define COMMAND_SKIPLIST 2 +#define TIMEPERIOD_SKIPLIST 3 +#define CONTACT_SKIPLIST 4 +#define CONTACTGROUP_SKIPLIST 5 +#define HOSTGROUP_SKIPLIST 6 +#define SERVICEGROUP_SKIPLIST 7 +#define HOSTDEPENDENCY_SKIPLIST 8 +#define SERVICEDEPENDENCY_SKIPLIST 9 +#define HOSTESCALATION_SKIPLIST 10 +#define SERVICEESCALATION_SKIPLIST 11 + + +/***************** DATE RANGE TYPES *******************/ + +#define DATERANGE_CALENDAR_DATE 0 /* 2008-12-25 */ +#define DATERANGE_MONTH_DATE 1 /* july 4 (specific month) */ +#define DATERANGE_MONTH_DAY 2 /* day 21 (generic month) */ +#define DATERANGE_MONTH_WEEK_DAY 3 /* 3rd thursday (specific month) */ +#define DATERANGE_WEEK_DAY 4 /* 3rd thursday (generic month) */ +#define DATERANGE_TYPES 5 + + +/* + * flags for notification_options, flapping_options and other similar + * flags. They overlap (hosts and services), so we can't use enum's. + */ +#define OPT_NOTHING 0 /* no options selected */ +#define OPT_ALL (~0) /* everything selected, so all bits set */ +#define OPT_DOWN (1 << HOST_DOWN) +#define OPT_UP (1 << HOST_UP) +#define OPT_UNREACHABLE (1 << HOST_UNREACHABLE) +#define OPT_OK (1 << STATE_OK) +#define OPT_WARNING (1 << STATE_WARNING) +#define OPT_CRITICAL (1 << STATE_CRITICAL) +#define OPT_UNKNOWN (1 << STATE_UNKNOWN) +#define OPT_RECOVERY OPT_OK +/* and now the "unreal" states... */ +#define OPT_PENDING (1 << 10) +#define OPT_FLAPPING (1 << 11) +#define OPT_DOWNTIME (1 << 12) +#define OPT_DISABLED (1 << 15) /* will denote disabled checks some day */ + +/* macros useful with both hosts and services */ +#define flag_set(c, flag) ((c) |= (flag)) +#define flag_get(c, flag) (unsigned int)((c) & (flag)) +#define flag_isset(c, flag) (flag_get((c), (flag)) == (unsigned int)(flag)) +#define flag_unset(c, flag) (c &= ~(flag)) +#define should_stalk(o) flag_isset(o->stalking_options, 1 << o->current_state) +#define should_flap_detect(o) flag_isset(o->flap_detection_options, 1 << o->current_state) +#define should_notify(o) flag_isset(o->notification_options, 1 << o->current_state) +#define add_notified_on(o, f) (o->notified_on |= (1 << f)) + + +/****************** DATA STRUCTURES *******************/ + +/* @todo Remove typedef's of non-opaque types in Nagios 5 */ +typedef struct host host; +typedef struct service service; +typedef struct contact contact; + +/* TIMED_EVENT structure */ +typedef struct timed_event { + int event_type; + time_t run_time; + int recurring; + unsigned long event_interval; + int compensate_for_time_change; + void *timing_func; + void *event_data; + void *event_args; + int event_options; + unsigned int priority; /* 0 is auto, 1 is highest. n+1 < n */ + struct squeue_event *sq_event; + } timed_event; + + +/* NOTIFY_LIST structure */ +typedef struct notify_list { + struct contact *contact; + struct notify_list *next; + } notification; + + +/* + * *name can be "Nagios Core", "Merlin", "mod_gearman" or "DNX", fe. + * source_name gets passed the 'source' pointer from check_result + * and must return a non-free()'able string useful for printing what + * we need to determine exactly where the check was received from, + * such as "mod_gearman worker@10.11.12.13", or "Nagios Core command + * file worker" (for passive checks submitted locally), which will be + * stashed with hosts and services and used as the "CHECKSOURCE" macro. + */ +struct check_engine { + char *name; /* "Nagios Core", "Merlin", "Mod Gearman" fe */ + const char *(*source_name)(void *); + void (*clean_result)(void *); +}; + +/* CHECK_RESULT structure */ +typedef struct check_result { + int object_check_type; /* is this a service or a host check? */ + char *host_name; /* host name */ + char *service_description; /* service description */ + int check_type; /* was this an active or passive service check? */ + int check_options; + int scheduled_check; /* was this a scheduled or an on-demand check? */ + int reschedule_check; /* should we reschedule the next check */ + char *output_file; /* what file is the output stored in? */ + FILE *output_file_fp; + double latency; + struct timeval start_time; /* time the service check was initiated */ + struct timeval finish_time; /* time the service check was completed */ + int early_timeout; /* did the service check timeout? */ + int exited_ok; /* did the plugin check return okay? */ + int return_code; /* plugin return code */ + char *output; /* plugin output */ + struct rusage rusage; /* resource usage by this check */ + struct check_engine *engine; /* where did we get this check from? */ + void *source; /* engine handles this */ + } check_result; + + +/* SCHED_INFO structure */ +typedef struct sched_info { + int total_services; + int total_scheduled_services; + int total_hosts; + int total_scheduled_hosts; + double average_services_per_host; + double average_scheduled_services_per_host; + unsigned long service_check_interval_total; + unsigned long host_check_interval_total; + double average_service_execution_time; + double average_service_check_interval; + double average_host_check_interval; + double average_service_inter_check_delay; + double average_host_inter_check_delay; + double service_inter_check_delay; + double host_inter_check_delay; + int service_interleave_factor; + int max_service_check_spread; + int max_host_check_spread; + time_t first_service_check; + time_t last_service_check; + time_t first_host_check; + time_t last_host_check; + } sched_info; + + +/* DBUF structure - dynamic string storage */ +typedef struct dbuf { + char *buf; + unsigned long used_size; + unsigned long allocated_size; + unsigned long chunk_size; + } dbuf; + + +#define CHECK_STATS_BUCKETS 15 + +/* used for tracking host and service check statistics */ +typedef struct check_stats { + int current_bucket; + int bucket[CHECK_STATS_BUCKETS]; + int overflow_bucket; + int minute_stats[3]; + time_t last_update; + } check_stats; + + + +/* OBJECT LIST STRUCTURE */ +typedef struct objectlist { + void *object_ptr; + struct objectlist *next; + } objectlist; + + +/* TIMERANGE structure */ +typedef struct timerange { + unsigned long range_start; + unsigned long range_end; + struct timerange *next; + } timerange; + + +/* DATERANGE structure */ +typedef struct daterange { + int type; + int syear; /* start year */ + int smon; /* start month */ + int smday; /* start day of month (may 3rd, last day in feb) */ + int swday; /* start day of week (thursday) */ + int swday_offset; /* start weekday offset (3rd thursday, last monday in jan) */ + int eyear; + int emon; + int emday; + int ewday; + int ewday_offset; + int skip_interval; + struct timerange *times; + struct daterange *next; + } daterange; + + +/* TIMEPERIODEXCLUSION structure */ +typedef struct timeperiodexclusion { + char *timeperiod_name; + struct timeperiod *timeperiod_ptr; + struct timeperiodexclusion *next; + } timeperiodexclusion; + + +/* TIMEPERIOD structure */ +typedef struct timeperiod { + unsigned int id; + char *name; + char *alias; + struct timerange *days[7]; + struct daterange *exceptions[DATERANGE_TYPES]; + struct timeperiodexclusion *exclusions; + struct timeperiod *next; + } timeperiod; + + +/* CONTACTSMEMBER structure */ +typedef struct contactsmember { + char *contact_name; + struct contact *contact_ptr; + struct contactsmember *next; + } contactsmember; + + +/* CONTACTGROUP structure */ +typedef struct contactgroup { + unsigned int id; + char *group_name; + char *alias; + struct contactsmember *members; + struct contactgroup *next; + } contactgroup; + + +/* CONTACTGROUPSMEMBER structure */ +typedef struct contactgroupsmember { + char *group_name; + struct contactgroup *group_ptr; + struct contactgroupsmember *next; + } contactgroupsmember; + + +/* CUSTOMVARIABLESMEMBER structure */ +typedef struct customvariablesmember { + char *variable_name; + char *variable_value; + int has_been_modified; + struct customvariablesmember *next; + } customvariablesmember; + + +/* COMMAND structure */ +typedef struct command { + unsigned int id; + char *name; + char *command_line; + struct command *next; + } command; + + +/* COMMANDSMEMBER structure */ +typedef struct commandsmember { + char *command; + struct command *command_ptr; + struct commandsmember *next; + } commandsmember; + + +/* CONTACT structure */ +struct contact { + unsigned int id; + char *name; + char *alias; + char *email; + char *pager; + char *address[MAX_CONTACT_ADDRESSES]; + struct commandsmember *host_notification_commands; + struct commandsmember *service_notification_commands; + unsigned int host_notification_options; + unsigned int service_notification_options; + unsigned int minimum_value; + char *host_notification_period; + char *service_notification_period; + int host_notifications_enabled; + int service_notifications_enabled; + int can_submit_commands; + int retain_status_information; + int retain_nonstatus_information; + struct customvariablesmember *custom_variables; +#ifndef NSCGI + time_t last_host_notification; + time_t last_service_notification; + unsigned long modified_attributes; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; +#endif + + struct timeperiod *host_notification_period_ptr; + struct timeperiod *service_notification_period_ptr; + struct objectlist *contactgroups_ptr; + struct contact *next; + }; + + +/* SERVICESMEMBER structure */ +typedef struct servicesmember { + char *host_name; + char *service_description; + struct service *service_ptr; + struct servicesmember *next; + } servicesmember; + + +/* HOSTSMEMBER structure */ +typedef struct hostsmember { + char *host_name; + struct host *host_ptr; + struct hostsmember *next; + } hostsmember; + + +/* HOSTGROUP structure */ +typedef struct hostgroup { + unsigned int id; + char *group_name; + char *alias; + struct hostsmember *members; + char *notes; + char *notes_url; + char *action_url; + struct hostgroup *next; + } hostgroup; + + +/* HOST structure */ +struct host { + unsigned int id; + char *name; + char *display_name; + char *alias; + char *address; + struct hostsmember *parent_hosts; + struct hostsmember *child_hosts; + struct servicesmember *services; + char *check_command; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + char *event_handler; + struct contactgroupsmember *contact_groups; + struct contactsmember *contacts; + double notification_interval; + double first_notification_delay; + unsigned int notification_options; + unsigned int hourly_value; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_options; + unsigned int stalking_options; + int check_freshness; + int freshness_threshold; + int process_performance_data; + int checks_enabled; + const char *check_source; + int accept_passive_checks; + int event_handler_enabled; + int retain_status_information; + int retain_nonstatus_information; + int obsess; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + char *statusmap_image; /* used by lots of graphing tools */ +/* #ifdef NSCGI */ + /* + * these are kept in ancillary storage for the daemon and + * thrown out as soon as we've created the object cache. + * The CGI's still attach them though, since they are the + * only users of this utter crap. + */ + char *vrml_image; + int have_2d_coords; + int x_2d; + int y_2d; + int have_3d_coords; + double x_3d; + double y_3d; + double z_3d; + int should_be_drawn; +/* #endif */ + customvariablesmember *custom_variables; +#ifndef NSCGI + int problem_has_been_acknowledged; + int acknowledgement_type; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int notifications_enabled; + time_t last_notification; + time_t next_notification; + time_t next_check; + int should_be_scheduled; + time_t last_check; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_up; + time_t last_time_down; + time_t last_time_unreachable; + int has_been_checked; + int is_being_freshened; + int notified_on; + int current_notification_number; + int no_more_notifications; + unsigned long current_notification_id; + int check_flapping_recovery_notification; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + time_t last_state_history_update; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + int total_services; + unsigned long total_service_check_interval; + unsigned long modified_attributes; +#endif + + struct command *event_handler_ptr; + struct command *check_command_ptr; + struct timeperiod *check_period_ptr; + struct timeperiod *notification_period_ptr; + struct objectlist *hostgroups_ptr; + /* objects we depend upon */ + struct objectlist *exec_deps, *notify_deps; + struct objectlist *escalation_list; + struct host *next; + struct timed_event *next_check_event; + }; + + +/* SERVICEGROUP structure */ +typedef struct servicegroup { + unsigned int id; + char *group_name; + char *alias; + struct servicesmember *members; + char *notes; + char *notes_url; + char *action_url; + struct servicegroup *next; + } servicegroup; + + +/* SERVICE structure */ +struct service { + unsigned int id; + char *host_name; + char *description; + char *display_name; + struct servicesmember *parents; + struct servicesmember *children; + char *check_command; + char *event_handler; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + int parallelize; + struct contactgroupsmember *contact_groups; + struct contactsmember *contacts; + double notification_interval; + double first_notification_delay; + unsigned int notification_options; + unsigned int stalking_options; + unsigned int hourly_value; + int is_volatile; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + unsigned int flap_detection_options; + int process_performance_data; + int check_freshness; + int freshness_threshold; + int accept_passive_checks; + int event_handler_enabled; + int checks_enabled; + const char *check_source; + int retain_status_information; + int retain_nonstatus_information; + int notifications_enabled; + int obsess; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + struct customvariablesmember *custom_variables; +#ifndef NSCGI + int problem_has_been_acknowledged; + int acknowledgement_type; + int host_problem_at_last_check; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + time_t next_check; + int should_be_scheduled; + time_t last_check; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int check_flapping_recovery_notification; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_ok; + time_t last_time_warning; + time_t last_time_unknown; + time_t last_time_critical; + int has_been_checked; + int is_being_freshened; + unsigned int notified_on; + int current_notification_number; + unsigned long current_notification_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + unsigned long modified_attributes; +#endif + + struct host *host_ptr; + struct command *event_handler_ptr; + char *event_handler_args; + struct command *check_command_ptr; + char *check_command_args; + struct timeperiod *check_period_ptr; + struct timeperiod *notification_period_ptr; + struct objectlist *servicegroups_ptr; + struct objectlist *exec_deps, *notify_deps; + struct objectlist *escalation_list; + struct service *next; + struct timed_event *next_check_event; + }; + + +/* SERVICE ESCALATION structure */ +typedef struct serviceescalation { + unsigned int id; + char *host_name; + char *description; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalation_options; + struct contactgroupsmember *contact_groups; + struct contactsmember *contacts; + struct service *service_ptr; + struct timeperiod *escalation_period_ptr; + } serviceescalation; + + +/* SERVICE DEPENDENCY structure */ +typedef struct servicedependency { + unsigned int id; + int dependency_type; + char *dependent_host_name; + char *dependent_service_description; + char *host_name; + char *service_description; + char *dependency_period; + int inherits_parent; + int failure_options; + struct service *master_service_ptr; + struct service *dependent_service_ptr; + struct timeperiod *dependency_period_ptr; + } servicedependency; + + +/* HOST ESCALATION structure */ +typedef struct hostescalation { + unsigned int id; + char *host_name; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalation_options; + struct contactgroupsmember *contact_groups; + struct contactsmember *contacts; + struct host *host_ptr; + struct timeperiod *escalation_period_ptr; + } hostescalation; + + +/* HOST DEPENDENCY structure */ +typedef struct hostdependency { + unsigned int id; + int dependency_type; + char *dependent_host_name; + char *host_name; + char *dependency_period; + int inherits_parent; + int failure_options; + struct host *master_host_ptr; + struct host *dependent_host_ptr; + struct timeperiod *dependency_period_ptr; + } hostdependency; + +extern struct command *command_list; +extern struct timeperiod *timeperiod_list; +extern struct host *host_list; +extern struct service *service_list; +extern struct contact *contact_list; +extern struct hostgroup *hostgroup_list; +extern struct servicegroup *servicegroup_list; +extern struct contactgroup *contactgroup_list; +extern struct hostescalation *hostescalation_list; +extern struct serviceescalation *serviceescalation_list; +extern struct command **command_ary; +extern struct timeperiod **timeperiod_ary; +extern struct host **host_ary; +extern struct service **service_ary; +extern struct contact **contact_ary; +extern struct hostgroup **hostgroup_ary; +extern struct servicegroup **servicegroup_ary; +extern struct contactgroup **contactgroup_ary; +extern struct hostescalation **hostescalation_ary; +extern struct hostdependency **hostdependency_ary; +extern struct serviceescalation **serviceescalation_ary; +extern struct servicedependency **servicedependency_ary; + + +/********************* FUNCTIONS **********************/ + +/**** Top-level input functions ****/ +int read_object_config_data(const char *, int); /* reads all external configuration data of specific types */ + + +/**** Object Creation Functions ****/ +struct contact *add_contact(char *name, char *alias, char *email, char *pager, char **addresses, char *svc_notification_period, char *host_notification_period, int service_notification_options, int host_notification_options, int service_notifications_enabled, int host_notifications_enabled, int can_submit_commands, int retain_status_information, int retain_nonstatus_information, unsigned int minimum_value); +struct commandsmember *add_service_notification_command_to_contact(contact *, char *); /* adds a service notification command to a contact definition */ +struct commandsmember *add_host_notification_command_to_contact(contact *, char *); /* adds a host notification command to a contact definition */ +struct customvariablesmember *add_custom_variable_to_contact(contact *, char *, char *); /* adds a custom variable to a service definition */ +struct host *add_host(char *name, char *display_name, char *alias, char *address, char *check_period, int initial_state, double check_interval, double retry_interval, int max_attempts, int notification_options, double notification_interval, double first_notification_delay, char *notification_period, int notifications_enabled, char *check_command, int checks_enabled, int accept_passive_checks, char *event_handler, int event_handler_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_options, int stalking_options, int process_perfdata, int check_freshness, int freshness_threshold, char *notes, char *notes_url, char *action_url, char *icon_image, char *icon_image_alt, char *vrml_image, char *statusmap_image, int x_2d, int y_2d, int have_2d_coords, double x_3d, double y_3d, double z_3d, int have_3d_coords, int should_be_drawn, int retain_status_information, int retain_nonstatus_information, int obsess_over_host, unsigned int hourly_value); +struct hostsmember *add_parent_host_to_host(host *, char *); /* adds a parent host to a host definition */ +struct servicesmember *add_parent_service_to_service(service *, char *host_name, char *description); +struct hostsmember *add_child_link_to_host(host *, host *); /* adds a child host to a host definition */ +struct contactgroupsmember *add_contactgroup_to_host(host *, char *); /* adds a contactgroup to a host definition */ +struct contactsmember *add_contact_to_host(host *, char *); /* adds a contact to a host definition */ +struct customvariablesmember *add_custom_variable_to_host(host *, char *, char *); /* adds a custom variable to a host definition */ +struct timeperiod *add_timeperiod(char *, char *); /* adds a timeperiod definition */ +struct timeperiodexclusion *add_exclusion_to_timeperiod(timeperiod *, char *); /* adds an exclusion to a timeperiod */ +struct timerange *add_timerange_to_timeperiod(timeperiod *, int, unsigned long, unsigned long); /* adds a timerange to a timeperiod definition */ +struct daterange *add_exception_to_timeperiod(timeperiod *, int, int, int, int, int, int, int, int, int, int, int, int); +struct timerange *add_timerange_to_daterange(daterange *, unsigned long, unsigned long); +struct hostgroup *add_hostgroup(char *, char *, char *, char *, char *); /* adds a hostgroup definition */ +struct hostsmember *add_host_to_hostgroup(hostgroup *, char *); /* adds a host to a hostgroup definition */ +struct servicegroup *add_servicegroup(char *, char *, char *, char *, char *); /* adds a servicegroup definition */ +struct servicesmember *add_service_to_servicegroup(servicegroup *, char *, char *); /* adds a service to a servicegroup definition */ +struct contactgroup *add_contactgroup(char *, char *); /* adds a contactgroup definition */ +struct contactsmember *add_contact_to_contactgroup(contactgroup *, char *); /* adds a contact to a contact group definition */ +struct command *add_command(char *, char *); /* adds a command definition */ +struct service *add_service(char *host_name, char *description, char *display_name, char *check_period, int initial_state, int max_attempts, int parallelize, int accept_passive_checks, double check_interval, double retry_interval, double notification_interval, double first_notification_delay, char *notification_period, int notification_options, int notifications_enabled, int is_volatile, char *event_handler, int event_handler_enabled, char *check_command, int checks_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_options, int stalking_options, int process_perfdata, int check_freshness, int freshness_threshold, char *notes, char *notes_url, char *action_url, char *icon_image, char *icon_image_alt, int retain_status_information, int retain_nonstatus_information, int obsess_over_service, unsigned int hourly_value); +struct contactgroupsmember *add_contactgroup_to_service(service *, char *); /* adds a contact group to a service definition */ +struct contactsmember *add_contact_to_service(service *, char *); /* adds a contact to a host definition */ +struct serviceescalation *add_serviceescalation(char *host_name, char *description, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalation_options); +struct contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *, char *); /* adds a contact group to a service escalation definition */ +struct contactsmember *add_contact_to_serviceescalation(serviceescalation *, char *); /* adds a contact to a service escalation definition */ +struct customvariablesmember *add_custom_variable_to_service(service *, char *, char *); /* adds a custom variable to a service definition */ +struct servicedependency *add_service_dependency(char *dependent_host_name, char *dependent_service_description, char *host_name, char *service_description, int dependency_type, int inherits_parent, int failure_options, char *dependency_period); +struct hostdependency *add_host_dependency(char *dependent_host_name, char *host_name, int dependency_type, int inherits_parent, int failure_options, char *dependency_period); +struct hostescalation *add_hostescalation(char *host_name, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalation_options); +struct contactsmember *add_contact_to_hostescalation(hostescalation *, char *); /* adds a contact to a host escalation definition */ +struct contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *, char *); /* adds a contact group to a host escalation definition */ + +struct contactsmember *add_contact_to_object(contactsmember **, char *); /* adds a contact to an object */ +struct customvariablesmember *add_custom_variable_to_object(customvariablesmember **, char *, char *); /* adds a custom variable to an object */ + + +struct servicesmember *add_service_link_to_host(host *, service *); + + +int skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b); +int get_host_count(void); +int get_service_count(void); + + +int create_object_tables(unsigned int *); + +/**** Object Search Functions ****/ +struct timeperiod *find_timeperiod(const char *); +struct host *find_host(const char *); +struct hostgroup *find_hostgroup(const char *); +struct servicegroup *find_servicegroup(const char *); +struct contact *find_contact(const char *); +struct contactgroup *find_contactgroup(const char *); +struct command *find_command(const char *); +struct service *find_service(const char *, const char *); + + +#define OBJECTLIST_DUPE 1 +int add_object_to_objectlist(struct objectlist **, void *); +int prepend_object_to_objectlist(struct objectlist **, void *); +int prepend_unique_object_to_objectlist(struct objectlist **, void *, size_t size); +int free_objectlist(objectlist **); + + +/**** Object Query Functions ****/ +unsigned int host_services_value(struct host *h); +int is_host_immediate_child_of_host(struct host *, struct host *); /* checks if a host is an immediate child of another host */ +int is_host_primary_immediate_child_of_host(struct host *, struct host *); /* checks if a host is an immediate child (and primary child) of another host */ +int is_host_immediate_parent_of_host(struct host *, struct host *); /* checks if a host is an immediate child of another host */ +int is_host_member_of_hostgroup(struct hostgroup *, struct host *); /* tests whether or not a host is a member of a specific hostgroup */ +int is_host_member_of_servicegroup(struct servicegroup *, struct host *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_service_member_of_servicegroup(struct servicegroup *, struct service *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_contact_member_of_contactgroup(struct contactgroup *, struct contact *); /* tests whether or not a contact is a member of a specific contact group */ +int is_contact_for_host(struct host *, struct contact *); /* tests whether or not a contact is a contact member for a specific host */ +int is_escalated_contact_for_host(struct host *, struct contact *); /* checks whether or not a contact is an escalated contact for a specific host */ +int is_contact_for_service(struct service *, struct contact *); /* tests whether or not a contact is a contact member for a specific service */ +int is_escalated_contact_for_service(struct service *, struct contact *); /* checks whether or not a contact is an escalated contact for a specific service */ + +int number_of_immediate_child_hosts(struct host *); /* counts the number of immediate child hosts for a particular host */ +int number_of_total_child_hosts(struct host *); /* counts the number of total child hosts for a particular host */ +int number_of_immediate_parent_hosts(struct host *); /* counts the number of immediate parents hosts for a particular host */ + +#ifndef NSCGI +void fcache_contactlist(FILE *fp, const char *prefix, struct contactsmember *list); +void fcache_contactgrouplist(FILE *fp, const char *prefix, struct contactgroupsmember *list); +void fcache_hostlist(FILE *fp, const char *prefix, struct hostsmember *list); +void fcache_customvars(FILE *fp, struct customvariablesmember *cvlist); +void fcache_timeperiod(FILE *fp, struct timeperiod *temp_timeperiod); +void fcache_command(FILE *fp, struct command *temp_command); +void fcache_contactgroup(FILE *fp, struct contactgroup *temp_contactgroup); +void fcache_hostgroup(FILE *fp, struct hostgroup *temp_hostgroup); +void fcache_servicegroup(FILE *fp, struct servicegroup *temp_servicegroup); +void fcache_contact(FILE *fp, struct contact *temp_contact); +void fcache_host(FILE *fp, struct host *temp_host); +void fcache_service(FILE *fp, struct service *temp_service); +void fcache_servicedependency(FILE *fp, struct servicedependency *temp_servicedependency); +void fcache_serviceescalation(FILE *fp, struct serviceescalation *temp_serviceescalation); +void fcache_hostdependency(FILE *fp, struct hostdependency *temp_hostdependency); +void fcache_hostescalation(FILE *fp, struct hostescalation *temp_hostescalation); +int fcache_objects(char *cache_file); +#endif + + +/**** Object Cleanup Functions ****/ +int free_object_data(void); /* frees all allocated memory for the object definitions */ + + +NAGIOS_END_DECL +#endif diff --git a/nagios4/perfdata.h b/nagios4/perfdata.h new file mode 100644 index 0000000..484849f --- /dev/null +++ b/nagios4/perfdata.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * + * PERFDATA.H - Include file for performance data routines + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _PERFDATA_H +#define _PERFDATA_H + +#include "common.h" +#include "objects.h" + +NAGIOS_BEGIN_DECL + +int initialize_performance_data(const char *); /* initializes performance data */ +int cleanup_performance_data(void); /* cleans up performance data */ + +int update_host_performance_data(host *); /* updates host performance data */ +int update_service_performance_data(service *); /* updates service performance data */ + +NAGIOS_END_DECL +#endif diff --git a/nagios4/pqueue.h b/nagios4/pqueue.h new file mode 100644 index 0000000..a944cf3 --- /dev/null +++ b/nagios4/pqueue.h @@ -0,0 +1,185 @@ +/* + * Copyright 2010 Volkan Yazıcı + * Copyright 2006-2010 The Apache Software Foundation + * + * 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 LIBNAGIOS_pqueue_h__ +#define LIBNAGIOS_pqueue_h__ +#include + +/** + * @file pqueue.h + * @brief Priority Queue function declarations + * + * This priority queue library was originally written by Volkan Yazici + * . It was lated adapted for Nagios by + * Andreas Ericsson . Changes compared to the original + * version are pretty much limited to changing pqueue_pri_t to be + * an unsigned long long instead of a double, since ULL comparisons + * are 107 times faster on my 64-bit laptop. + * + * @{ + */ + + +/** priority data type (used to be double, but ull is 107 times faster) */ +typedef unsigned long long pqueue_pri_t; + +/** callback functions to get/set/compare the priority of an element */ +typedef pqueue_pri_t (*pqueue_get_pri_f)(void *a); +typedef void (*pqueue_set_pri_f)(void *a, pqueue_pri_t pri); +typedef int (*pqueue_cmp_pri_f)(pqueue_pri_t next, pqueue_pri_t curr); + + +/** callback functions to get/set the position of an element */ +typedef unsigned int (*pqueue_get_pos_f)(void *a); +typedef void (*pqueue_set_pos_f)(void *a, unsigned int pos); + + +/** debug callback function to print a entry */ +typedef void (*pqueue_print_entry_f)(FILE *out, void *a); + + +/** the priority queue handle */ +typedef struct pqueue_t +{ + unsigned int size; /**< number of elements in this queue */ + unsigned int avail; /**< slots available in this queue */ + unsigned int step; /**< growth stepping setting */ + pqueue_cmp_pri_f cmppri; /**< callback to compare nodes */ + pqueue_get_pri_f getpri; /**< callback to get priority of a node */ + pqueue_set_pri_f setpri; /**< callback to set priority of a node */ + pqueue_get_pos_f getpos; /**< callback to get position of a node */ + pqueue_set_pos_f setpos; /**< callback to set position of a node */ + void **d; /**< The actualy queue in binary heap form */ +} pqueue_t; + + +/** + * initialize the queue + * + * @param n the initial estimate of the number of queue items for which memory + * should be preallocated + * @param cmppri The callback function to run to compare two elements + * This callback should return 0 for 'lower' and non-zero + * for 'higher', or vice versa if reverse priority is desired + * @param setpri the callback function to run to assign a score to an element + * @param getpri the callback function to run to set a score to an element + * @param getpos the callback function to get the current element's position + * @param setpos the callback function to set the current element's position + * + * @return the handle or NULL for insufficent memory + */ +pqueue_t * +pqueue_init(unsigned int n, + pqueue_cmp_pri_f cmppri, + pqueue_get_pri_f getpri, + pqueue_set_pri_f setpri, + pqueue_get_pos_f getpos, + pqueue_set_pos_f setpos); + + +/** + * free all memory used by the queue + * @param q the queue + */ +void pqueue_free(pqueue_t *q); + + +/** + * return the size of the queue. + * @param q the queue + */ +unsigned int pqueue_size(pqueue_t *q); + + +/** + * insert an item into the queue. + * @param q the queue + * @param d the item + * @return 0 on success + */ +int pqueue_insert(pqueue_t *q, void *d); + + +/** + * move an existing entry to a different priority + * @param q the queue + * @param new_pri the new priority + * @param d the entry + */ +void +pqueue_change_priority(pqueue_t *q, + pqueue_pri_t new_pri, + void *d); + + +/** + * pop the highest-ranking item from the queue. + * @param q the queue + * @return NULL on error, otherwise the entry + */ +void *pqueue_pop(pqueue_t *q); + + +/** + * remove an item from the queue. + * @param q the queue + * @param d the entry + * @return 0 on success + */ +int pqueue_remove(pqueue_t *q, void *d); + + +/** + * access highest-ranking item without removing it. + * @param q the queue + * @return NULL on error, otherwise the entry + */ +void *pqueue_peek(pqueue_t *q); + + +/** + * print the queue + * @internal + * DEBUG function only + * @param q the queue + * @param out the output handle + * @param the callback function to print the entry + */ +void +pqueue_print(pqueue_t *q, FILE *out, pqueue_print_entry_f print); + + +/** + * dump the queue and it's internal structure + * @internal + * debug function only + * @param q the queue + * @param out the output handle + * @param the callback function to print the entry + */ +void pqueue_dump(pqueue_t *q, FILE *out, pqueue_print_entry_f print); + + +/** + * checks that the pq is in the right order, etc + * @internal + * debug function only + * @param q the queue + */ +int pqueue_is_valid(pqueue_t *q); + +#endif +/** @} */ diff --git a/nagios4/runcmd.h b/nagios4/runcmd.h new file mode 100644 index 0000000..151c8d5 --- /dev/null +++ b/nagios4/runcmd.h @@ -0,0 +1,96 @@ +#ifndef LIBNAGIOS_runcmd_h__ +#define LIBNAGIOS_runcmd_h__ +#include + +/** + * @file runcmd.h + * @brief runcmd library function declarations + * + * @note This is inherited from the nagiosplugins project, although + * I (AE) wrote the original code, and it might need refactoring + * for performance later. + * @{ + */ + +/** Return code bitflags for runcmd_cmd2strv() */ +#define RUNCMD_HAS_REDIR (1 << 0) /**< I/O redirection */ +#define RUNCMD_HAS_SUBCOMMAND (1 << 1) /**< subcommands present */ +#define RUNCMD_HAS_PAREN (1 << 2) /**< parentheses present in command */ +#define RUNCMD_HAS_JOBCONTROL (1 << 3) /**< job control stuff present */ +#define RUNCMD_HAS_UBSQ (1 << 4) /**< unbalanced single quotes */ +#define RUNCMD_HAS_UBDQ (1 << 5) /**< unbalanced double quotes */ +#define RUNCMD_HAS_WILDCARD (1 << 6) /**< wildcards present */ +#define RUNCMD_HAS_SHVAR (1 << 7) /**< shell variables present */ + + +#define RUNCMD_EFD (-1) /**< Failed to pipe() or open() */ +#define RUNCMD_EALLOC (-2) /**< Failed to alloc */ +#define RUNCMD_ECMD (-3) /**< Bad command */ +#define RUNCMD_EFORK (-4) /**< Failed to fork() */ +#define RUNCMD_EINVAL (-5) /**< Invalid parameters */ +#define RUNCMD_EWAIT (-6) /**< Failed to wait() */ + +/** + * Initialize the runcmd library. + * + * Only multi-threaded programs that might launch the first external + * program from multiple threads simultaneously need to bother with + * this. + */ +extern void runcmd_init(void); + +/** + * Return pid of a command with a specific file descriptor + * @param[in] fd stdout filedescriptor of the child to get pid from + * @return pid of the child, or 0 on errors + */ +extern pid_t runcmd_pid(int fd); + +/** + * Return explanation of which system call or operation failed + * @param code Error code returned by a library function + * @return A non-free()'able string explaining where the error occurred + */ +extern const char *runcmd_strerror(int code); + +/** + * Start a command from a command string + * @param[in] cmdstring The command to launch + * @param[out] pfd Child's stdout filedescriptor + * @param[out] pfderr Child's stderr filedescriptor + * @param[in] env Currently ignored for portability + * @param[in] iobreg The callback function to register the iobrokers for the read ends of the pipe + * @param[in] iobregarg The "arg" value to pass to iobroker_register() + */ +extern int runcmd_open(const char *cmd, int *pfd, int *pfderr, char **env, + void (*iobreg)(int, int, void *), void *iobregarg) + __attribute__((__nonnull__(1, 2, 3, 5, 6))); + +/** + * Close a command and return its exit status + * @note Don't use this. It's a retarded way to reap children suitable + * only for launching a one-shot program. + * + * @param[in] fd The child's stdout filedescriptor + * @return exit-status of the child, or -1 in case of errors + */ +extern int runcmd_close(int fd); + +/** + * Convert a string to a vector of arguments like a shell would + * @note This might have bugs and is only tested to behave similar + * to how /bin/sh does things. For csh or other non bash-ish shells + * there are no guarantees. + * @note The out_argv array has to be large enough to hold all strings + * found in the command. + * @param[in] str The string to convert to an argument vector + * @param[out] out_argc The number of arguments found + * @param[out] out_argv The argument vector + * @return 0 on (great) success, or a bitmask of failure-codes + * representing f.e. unclosed quotes, job control or output redirection. + * See the RUNCMD_HAS_* and their ilk to find out about the flag. + */ +extern int runcmd_cmd2strv(const char *str, int *out_argc, char **out_argv); + +#endif /* INCLUDE_runcmd_h__ */ +/** @} */ diff --git a/nagios4/shared.h b/nagios4/shared.h new file mode 100644 index 0000000..92f9319 --- /dev/null +++ b/nagios4/shared.h @@ -0,0 +1,55 @@ +#ifndef INCLUDE__shared_h__ +#define INCLUDE__shared_h__ + +#include +#include "libnagios.h" + +NAGIOS_BEGIN_DECL + +/* mmapfile structure - used for reading files via mmap() */ +typedef struct mmapfile_struct { + char *path; + int mode; + int fd; + unsigned long file_size; + unsigned long current_position; + unsigned long current_line; + void *mmap_buf; + } mmapfile; + +/* official count of first-class objects */ +struct object_count { + unsigned int commands; + unsigned int timeperiods; + unsigned int hosts; + unsigned int hostescalations; + unsigned int hostdependencies; + unsigned int services; + unsigned int serviceescalations; + unsigned int servicedependencies; + unsigned int contacts; + unsigned int contactgroups; + unsigned int hostgroups; + unsigned int servicegroups; + }; + +extern struct object_count num_objects; + +extern void timing_point(const char *fmt, ...); /* print a message and the time since the first message */ +extern char *my_strtok(char *buffer, const char *tokens); +extern char *my_strsep(char **stringp, const char *delim); +extern mmapfile *mmap_fopen(const char *filename); +extern int mmap_fclose(mmapfile *temp_mmapfile); +extern char *mmap_fgets(mmapfile *temp_mmapfile); +extern char *mmap_fgets_multiline(mmapfile * temp_mmapfile); +extern void strip(char *buffer); +extern int hashfunc(const char *name1, const char *name2, int hashslots); +extern int compare_hashdata(const char *val1a, const char *val1b, const char *val2a, + const char *val2b); +extern void get_datetime_string(time_t *raw_time, char *buffer, + int buffer_length, int type); +extern void get_time_breakdown(unsigned long raw_time, int *days, int *hours, + int *minutes, int *seconds); + +NAGIOS_END_DECL +#endif diff --git a/nagios4/skiplist.h b/nagios4/skiplist.h new file mode 100644 index 0000000..72ea4a7 --- /dev/null +++ b/nagios4/skiplist.h @@ -0,0 +1,162 @@ +/************************************************************************ + * + * SKIPLIST.H - Skiplist data structures and functions + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef LIBNAGIOS_skiplist_h__ +#define LIBNAGIOS_skiplist_h__ +#include "lnag-utils.h" + +/** + * @file skiplist.h + * @brief Skiplist library functions + * + * http://en.wikipedia.org/wiki/Skiplist + * + * @{ + */ + +#define SKIPLIST_OK 0 /**< A ok */ +#define SKIPLIST_ERROR_ARGS 1 /**< Bad arguments */ +#define SKIPLIST_ERROR_MEMORY 2 /**< Memory error */ +#define SKIPLIST_ERROR_DUPLICATE 3 /**< Trying to insert non-unique item */ + +NAGIOS_BEGIN_DECL + +struct skiplist_struct; +typedef struct skiplist_struct skiplist; + +/** + * Return number of items currently in the skiplist + * @param list The list to investigate + * @return number of items in list + */ +unsigned long skiplist_num_items(skiplist *list); + +/** + * Create a new skiplist + * @param max_levels Number of "ups" we have. + * This Should be kept close to lg2 of the number of items to store. + * @param level_probability Ignored + * @param allow_duplicates Allow duplicates in this list + * @param append_duplicates Append rather than prepend duplicates + * @param compare_function Comparison function for data entries + * @return pointer to a new skiplist on success, NULL on errors + */ +skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *, void *)); + +/** + * Insert an item into a skiplist + * @param list The list to insert to + * @param data The data to insert + * @return SKIPLIST_OK on success, or an error code + */ +int skiplist_insert(skiplist *list, void *data); + +/** + * Empty the skiplist of all data + * @param list The list to empty + * @return ERROR on failures. OK on success + */ +int skiplist_empty(skiplist *list); + +/** + * Free all nodes (but not all data) in a skiplist + * This is similar to skiplist_empty(), but also free()'s the head node + * @param list The list to free + * @return OK on success, ERROR on failures + */ +int skiplist_free(skiplist **list); + +/** + * Get the first item in the skiplist + * @param list The list to peek into + * @return The first item, or NULL if there is none + */ +void *skiplist_peek(skiplist *list); + +/** + * Pop the first item from the skiplist + * @param list The list to pop from + */ +void *skiplist_pop(skiplist *list); + +/** + * Get first node of skiplist + * @param list The list to search + * @param[out] node_ptr State variable for skiplist_get_next() + * @return The data-item of the first node on success, NULL on errors + */ +void *skiplist_get_first(skiplist *list, void **node_ptr); + +/** + * Get next item from node_ptr + * @param[out] node_ptr State variable primed from an earlier call to + * skiplist_get_first() or skiplist_get_next() + * @return The next data-item matching node_ptr on success, NULL on errors + */ +void *skiplist_get_next(void **node_ptr); + +/** + * Find first entry in skiplist matching data + * @param list The list to search + * @param data Comparison object used to search + * @param[out] node_ptr State variable for future lookups with + * skiplist_find_next() + * @return The first found data-item, of NULL if none could be found + */ +void *skiplist_find_first(skiplist *list, void *data, void **node_ptr); + +/** + * Find next entry in skiplist matching data + * @param list The list to search + * @param data The data to compare against + * @param[out] node_ptr State var primed from earlier call to + * skiplist_find_next() or skiplist_find_first() + * @return The next found data-item, or NULL if none could be found + */ +void *skiplist_find_next(skiplist *list, void *data, void **node_ptr); + +/** + * Delete all items matching 'data' from skiplist + * @param list The list to delete from + * @param data Comparison object used to find the real node + * @return OK on success, ERROR on errors + */ +int skiplist_delete(skiplist *list, void *data); + +/** + * Delete first item matching 'data' from skiplist + * @param list The list to delete from + * @param data Comparison object used to search the list + * @return OK on success, ERROR on errors. + */ +int skiplist_delete_first(skiplist *list, void *data); + +/** + * Delete a particular node from the skiplist + * @param list The list to search + * @param node_ptr The node to delete + * @return OK on success, ERROR on errors. + */ +int skiplist_delete_node(skiplist *list, void *node_ptr); + +NAGIOS_END_DECL +/* @} */ +#endif diff --git a/nagios4/snprintf.h b/nagios4/snprintf.h new file mode 100644 index 0000000..2e5d0b0 --- /dev/null +++ b/nagios4/snprintf.h @@ -0,0 +1,7 @@ +/* lib/snprintf.h. Generated from snprintf.h.in by configure. */ +/* -*- C -*- */ +#ifndef LIBNAGIOS_snprintf_h__ +#define LIBNAGIOS_snprintf_h__ +/* #undef HAVE_SNPRINTF */ +/* #undef NEED_VA_LIST */ +#endif diff --git a/nagios4/squeue.h b/nagios4/squeue.h new file mode 100644 index 0000000..8823a1b --- /dev/null +++ b/nagios4/squeue.h @@ -0,0 +1,161 @@ +#ifndef LIBNAGIOS_squeue_h__ +#define LIBNAGIOS_squeue_h__ +#include +#include +#include "pqueue.h" +/** + * @file squeue.h + * @brief Scheduling queue function declarations + * + * This library is based on the pqueue api, which implements a + * priority queue based on a binary heap, providing O(lg n) times + * for insert() and remove(), and O(1) time for peek(). + * @note There is no "find". Callers must maintain pointers to their + * scheduled events if they wish to be able to remove them. + * + * @{ + */ + +/* + * All opaque types here. + * The pqueue library can be useful on its own though, so we + * don't block that from user view. + */ +typedef pqueue_t squeue_t; +struct squeue_event; +typedef struct squeue_event squeue_event; + +/** + * Options for squeue_destroy()'s flag parameter + */ +#define SQUEUE_FREE_DATA (1 << 0) /** Call free() on all data pointers */ + +/** + * Get the scheduled runtime of this event + * @param[in] evt The event to get runtime of + * @return struct timeval on success, NULL on errors + */ +extern const struct timeval *squeue_event_runtime(squeue_event *evt); + +/** + * Get data of an squeue_event struct + * @param[in] evt The event to operate on + * @return The data object pointed to by the event + */ +extern void *squeue_event_data(squeue_event *evt); + +/** + * Creates a scheduling queue optimized for handling events within + * the given timeframe. Callers should take care to create a queue + * of a decent but not overly large size, as too small or too large + * a queue will impact performance negatively. A queue can hold any + * number of events. A good value for "horizon" would be the max + * seconds into the future one expects to schedule things, although + * with few scheduled items in that timeframe you'd be better off + * using a more narrow horizon. + * + * @param size Hint about how large this queue will get + * @return A pointer to a scheduling queue + */ +extern squeue_t *squeue_create(unsigned int size); + +/** + * Destroys a scheduling queue completely + * @param[in] q The doomed queue + * @param[in] flags Flags determining the the level of destruction + */ +extern void squeue_destroy(squeue_t *q, int flags); + +/** + * Enqueue an event with microsecond precision. + * It's up to the caller to keep the event pointer in case he/she + * wants to remove the event from the queue later. + * + * @param q The scheduling queue to add to + * @param tv When this event should occur + * @param data Pointer to any kind of data + * @return The complete scheduled event + */ +extern squeue_event *squeue_add_tv(squeue_t *q, struct timeval *tv, void *data); + +/** + * Adds an event to the scheduling queue. + * See notes for squeue_add_tv() for details + * + * @param q The scheduling queue to add to + * @param when The unix timestamp when this event is to occur + * @param data Pointer to any kind of data + * @return The complete scheduled event + */ +extern squeue_event *squeue_add(squeue_t *q, time_t when, void *data); + +/** + * Adds an event to the scheduling queue with millisecond precision + * See notes on squeue_add_tv() for details + * + * @param[in] q The scheduling queue to add to + * @param[in] when Unix timestamp when this event should occur + * @param[in] usec Millisecond of above this event should occur + * @param[in] data Pointer to any kind of data + * @return NULL on errors. squeue_event pointer on success + */ +extern squeue_event *squeue_add_usec(squeue_t *q, time_t when, time_t usec, void *data); + +/** + * Adds an event to the scheduling queue with millisecond precision + * See notes on squeue_add_tv() for details + * + * @param[in] q The scheduling queue to add to + * @param[in] when Unix timestamp when this event should occur + * @param[in] msec Millisecond of above this event should occur + * @param[in] data Pointer to any kind of data + * @return NULL on errors. squeue_event pointer on success + */ +extern squeue_event *squeue_add_msec(squeue_t *q, time_t when, time_t msec, void *data); + +/** + * Returns the data of the next scheduled event from the scheduling + * queue without removing it from the queue. + * + * @param q The scheduling queue to peek into + */ +extern void *squeue_peek(squeue_t *q); + +/** + * Pops the next scheduled event from the scheduling queue and + * returns the data for it. + * This is equivalent to squeue_peek() + squeue_pop() + * @note This causes the squeue_event to be free()'d. + * + * @param q The scheduling queue to pop from + */ +extern void *squeue_pop(squeue_t *q); + +/** + * Removes the given event from the scheduling queue + * @note This causes the associated squeue_event() to be free()'d. + * @param[in] q The scheduling queue to remove from + * @param[in] evt The event to remove + */ +extern int squeue_remove(squeue_t *q, squeue_event *evt); + +/** + * Returns the number of events in the scheduling queue. This + * function never fails. + * + * @param[in] q The scheduling queue to inspect + * @return number of events in the inspected queue + */ +extern unsigned int squeue_size(squeue_t *q); + + +/** + * Returns true if passed timeval is after the time for the event + * + * @param[in] evt The queue event to inspect + * @param[in] reftime The reference time to compare to the queue event time + * @return 1 if reftime > event time, 0 otherwise + */ +extern int squeue_evt_when_is_after(squeue_event *evt, struct timeval *reftime); +#endif +/** @} */ diff --git a/nagios4/sretention.h b/nagios4/sretention.h new file mode 100644 index 0000000..5485c24 --- /dev/null +++ b/nagios4/sretention.h @@ -0,0 +1,31 @@ +/***************************************************************************** + * + * SRETENTION.H - Header for state retention routines + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include "common.h" +NAGIOS_BEGIN_DECL + +int initialize_retention_data(const char *); +int cleanup_retention_data(void); +int save_state_information(int); /* saves all host and state information */ +int read_initial_state_information(void); /* reads in initial host and state information */ + +NAGIOS_END_DECL diff --git a/nagios4/statusdata.h b/nagios4/statusdata.h new file mode 100644 index 0000000..bc2ea08 --- /dev/null +++ b/nagios4/statusdata.h @@ -0,0 +1,199 @@ +/***************************************************************************** + * + * STATUSDATA.H - Header for external status data routines + * + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _STATUSDATA_H +#define _STATUSDATA_H + +#include "common.h" +#include "objects.h" + +#ifdef NSCGI +#define READ_PROGRAM_STATUS 1 +#define READ_HOST_STATUS 2 +#define READ_SERVICE_STATUS 4 +#define READ_CONTACT_STATUS 8 + +#define READ_ALL_STATUS_DATA READ_PROGRAM_STATUS | READ_HOST_STATUS | READ_SERVICE_STATUS | READ_CONTACT_STATUS + + + + /*************************** CHAINED HASH LIMITS ***************************/ + +#define SERVICESTATUS_HASHSLOTS 1024 +#define HOSTSTATUS_HASHSLOTS 1024 + + + /**************************** DATA STRUCTURES ******************************/ + +NAGIOS_BEGIN_DECL + +/* HOST STATUS structure */ +typedef struct hoststatus_struct { + char *host_name; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int status; + time_t last_update; + int has_been_checked; + int should_be_scheduled; + int current_attempt; + int max_attempts; + time_t last_check; + time_t next_check; + int check_options; + int check_type; + time_t last_state_change; + time_t last_hard_state_change; + int last_hard_state; + time_t last_time_up; + time_t last_time_down; + time_t last_time_unreachable; + int state_type; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int notifications_enabled; + int problem_has_been_acknowledged; + int acknowledgement_type; + int current_notification_number; + int accept_passive_checks; + int event_handler_enabled; + int checks_enabled; + int flap_detection_enabled; + int is_flapping; + double percent_state_change; + double latency; + double execution_time; + int scheduled_downtime_depth; + int process_performance_data; + int obsess; + struct hoststatus_struct *next; + struct hoststatus_struct *nexthash; + } hoststatus; + + +/* SERVICE STATUS structure */ +typedef struct servicestatus_struct { + char *host_name; + char *description; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int max_attempts; + int current_attempt; + int status; + time_t last_update; + int has_been_checked; + int should_be_scheduled; + time_t last_check; + time_t next_check; + int check_options; + int check_type; + int checks_enabled; + time_t last_state_change; + time_t last_hard_state_change; + int last_hard_state; + time_t last_time_ok; + time_t last_time_warning; + time_t last_time_unknown; + time_t last_time_critical; + int state_type; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int notifications_enabled; + int problem_has_been_acknowledged; + int acknowledgement_type; + int current_notification_number; + int accept_passive_checks; + int event_handler_enabled; + int flap_detection_enabled; + int is_flapping; + double percent_state_change; + double latency; + double execution_time; + int scheduled_downtime_depth; + int process_performance_data; + int obsess; + struct servicestatus_struct *next; + struct servicestatus_struct *nexthash; + } servicestatus; + + +/*************************** SERVICE STATES ***************************/ + +#define SERVICE_PENDING 1 +#define SERVICE_OK 2 +#define SERVICE_WARNING 4 +#define SERVICE_UNKNOWN 8 +#define SERVICE_CRITICAL 16 + + + +/**************************** HOST STATES ****************************/ + +#define HOST_PENDING 1 +#define SD_HOST_UP 2 +#define SD_HOST_DOWN 4 +#define SD_HOST_UNREACHABLE 8 + +/* Convert the (historically ordered) host states into a notion of "urgency". + This is defined as, in ascending order: + SD_HOST_UP (business as usual) + HOST_PENDING (waiting for - supposedly first - check result) + SD_HOST_UNREACHABLE (a problem, but likely not its cause) + SD_HOST_DOWN (look here!!) + The exact values are irrelevant, so I try to make the conversion as + CPU-efficient as possible: */ +#define HOST_URGENCY(hs) ((hs)|(((hs)&0x5)<<1)) + + + +/**************************** FUNCTIONS ******************************/ + +int read_status_data(const char *, int); /* reads all status data */ +int add_host_status(hoststatus *); /* adds a host status entry to the list in memory */ +int add_service_status(servicestatus *); /* adds a service status entry to the list in memory */ + +int add_hoststatus_to_hashlist(hoststatus *); +int add_servicestatus_to_hashlist(servicestatus *); + +servicestatus *find_servicestatus(char *, char *); /* finds status information for a specific service */ +hoststatus *find_hoststatus(char *); /* finds status information for a specific host */ +int get_servicestatus_count(char *, int); /* gets total number of services of a certain type for a specific host */ + +void free_status_data(void); /* free all memory allocated to status data */ +#endif + +#ifndef NSCGI +int initialize_status_data(const char *); /* initializes status data at program start */ +int update_all_status_data(void); /* updates all status data */ +int cleanup_status_data(int); /* cleans up status data at program termination */ +int update_program_status(int); /* updates program status data */ +int update_host_status(host *, int); /* updates host status data */ +int update_service_status(service *, int); /* updates service status data */ +int update_contact_status(contact *, int); /* updates contact status data */ +#endif + +NAGIOS_END_DECL +#endif diff --git a/nagios4/worker.h b/nagios4/worker.h new file mode 100644 index 0000000..dd69b41 --- /dev/null +++ b/nagios4/worker.h @@ -0,0 +1,132 @@ +#ifndef LIBNAGIOS_worker_h__ +#define LIBNAGIOS_worker_h__ +#include +#include +#include +#include +#include +#include +#include +#include "libnagios.h" + +/** + * @file worker.h + * @brief Worker implementation along with various helpers + * + * This code isn't really in the "library" category, but it's tucked + * in here to provide a good resource for writing remote workers and + * as an example on how to use the API's found here. + */ + +#ifndef ETIME +#define ETIME ETIMEDOUT +#endif + +typedef struct iobuf { + int fd; + unsigned int len; + char *buf; +} iobuf; + +typedef struct execution_information execution_information; + +typedef struct child_process { + unsigned int id, timeout; + char *cmd; + int ret; + struct kvvec *request; + iobuf outstd; + iobuf outerr; + execution_information *ei; +} child_process; + +/** + * Callback for enter_worker that simply runs a command + */ +extern int start_cmd(child_process *cp); + +/** + * Spawn a helper with a specific process name + * The first entry in the argv parameter will be the name of the + * new process, unless the process changes the name itself. + * @param path The path to the executable (can be $PATH relative) + * @param argv Argument vector for the helper to spawn + */ +extern int spawn_named_helper(char *path, char **argv); + +/** + * Spawn any random helper process. Uses spawn_named_helper() + * @param argv The (NULL-sentinel-terminated) argument vector + * @return 0 on success, < 0 on errors + */ +extern int spawn_helper(char **argv); + +/** + * To be called when a child_process has completed to ship the result to nagios + * @param cp The child_process that describes the job + * @param reason 0 if everything was OK, 1 if the job was unable to run + * @return 0 on success, non-zero otherwise + */ +extern int finish_job(child_process *cp, int reason); + +/** + * Start to poll the socket and call the callback when there are new tasks + * @param sd A socket descriptor to poll + * @param cb The callback to call upon completion + */ +extern void enter_worker(int sd, int (*cb)(child_process*)); + +/** + * Build a buffer from a key/value vector buffer. + * The resulting kvvec-buffer is suitable for sending between + * worker and master in either direction, as it has all the + * right delimiters in all the right places. + * @param kvv The key/value vector to build the buffer from + * @return NULL on errors, a newly allocated kvvec buffer on success + */ +extern struct kvvec_buf *build_kvvec_buf(struct kvvec *kvv); + +/** + * Send a key/value vector as a bytestream through a socket + * @param[in] sd The socket descriptor to send to + * @param kvv The key/value vector to send + * @return The number of bytes sent, or -1 on errors + */ +extern int worker_send_kvvec(int sd, struct kvvec *kvv); + +/** @deprecated Use worker_send_kvvec() instead */ +extern int send_kvvec(int sd, struct kvvec *kvv) + NAGIOS_DEPRECATED(4.1.0, "worker_send_kvvec()"); + +/** + * Grab a worker message from an iocache buffer + * @param[in] ioc The io cache + * @param[out] size Out buffer for buffer length + * @param[in] flags Currently unused + * @return A buffer from the iocache on succes; NULL on errors + */ +extern char *worker_ioc2msg(iocache *ioc, unsigned long *size, int flags); + +/** + * Parse a worker message to a preallocated key/value vector + * + * @param[in] kvv Key/value vector to fill + * @param[in] buf The buffer to parse + * @param[in] len Length of 'buf' + * @param[in] kvv_flags Flags for buf2kvvec() + * @return 0 on success, < 0 on errors + */ +extern int worker_buf2kvvec_prealloc(struct kvvec *kvv, char *buf, unsigned long len, int kvv_flags); + +/** + * Set some common socket options + * @param[in] sd The socket to set options for + * @param[in] bufsize Size to set send and receive buffers to + * @return 0 on success. < 0 on errors + */ +extern int worker_set_sockopts(int sd, int bufsize); + +/** @deprecated Use worker_set_sockopts() instead */ +extern int set_socket_options(int sd, int bufsize) + NAGIOS_DEPRECATED(4.1.0, "worker_set_sockopts()"); +#endif /* INCLUDE_worker_h__ */ diff --git a/src/Aggregator.h b/src/Aggregator.h new file mode 100644 index 0000000..64476c1 --- /dev/null +++ b/src/Aggregator.h @@ -0,0 +1,51 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Aggregator_h +#define Aggregator_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "Renderer.h" +#include "Row.h" +#include "contact_fwd.h" +class Query; + +class Aggregation { +public: + virtual ~Aggregation() = default; + virtual void update(double value) = 0; + [[nodiscard]] virtual double value() const = 0; +}; + +class Aggregator { +public: + virtual ~Aggregator() = default; + virtual void consume(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) = 0; + virtual void output(RowRenderer &r) const = 0; +}; + +#endif // Aggregator_h diff --git a/src/AndingFilter.cc b/src/AndingFilter.cc new file mode 100644 index 0000000..ff1e988 --- /dev/null +++ b/src/AndingFilter.cc @@ -0,0 +1,167 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "AndingFilter.h" +#include +#include +#include +#include +#include +#include +#include "Filter.h" +#include "OringFilter.h" +#include "Row.h" + +// static +std::unique_ptr AndingFilter::make(Kind kind, Filters subfilters) { + Filters filters; + for (const auto &filter : subfilters) { + if (filter->is_contradiction()) { + return OringFilter::make(kind, Filters()); + } + auto conjuncts = filter->conjuncts(); + filters.insert(filters.end(), + std::make_move_iterator(conjuncts.begin()), + std::make_move_iterator(conjuncts.end())); + } + return filters.size() == 1 ? std::move(filters[0]) + : std::make_unique( + kind, std::move(filters), Secret()); +} + +bool AndingFilter::accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const { + for (const auto &filter : _subfilters) { + if (!filter->accepts(row, auth_user, timezone_offset)) { + return false; + } + } + return true; +} + +std::unique_ptr AndingFilter::partialFilter( + std::function predicate) const { + Filters filters; + std::transform( + _subfilters.begin(), _subfilters.end(), std::back_inserter(filters), + [&](const auto &filter) { return filter->partialFilter(predicate); }); + return make(kind(), std::move(filters)); +} + +std::optional AndingFilter::stringValueRestrictionFor( + const std::string &column_name) const { + for (const auto &filter : _subfilters) { + if (auto value = filter->stringValueRestrictionFor(column_name)) { + return {value}; + } + } + return {}; +} + +std::optional AndingFilter::greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + std::optional result; + for (const auto &filter : _subfilters) { + if (auto glb = + filter->greatestLowerBoundFor(column_name, timezone_offset)) { + result = result ? std::max(*result, *glb) : glb; + } + } + return result; +} + +std::optional AndingFilter::leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + std::optional result; + for (const auto &filter : _subfilters) { + if (auto lub = + filter->leastUpperBoundFor(column_name, timezone_offset)) { + result = result ? std::min(*result, *lub) : lub; + } + } + return result; +} + +std::optional> AndingFilter::valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + std::optional> result; + for (const auto &filter : _subfilters) { + if (auto foo = filter->valueSetLeastUpperBoundFor(column_name, + timezone_offset)) { + result = result ? (*result & *foo) : foo; + } + } + return result; +} + +std::unique_ptr AndingFilter::copy() const { + return make(kind(), conjuncts()); +} + +std::unique_ptr AndingFilter::negate() const { + Filters filters; + std::transform(_subfilters.begin(), _subfilters.end(), + std::back_inserter(filters), + [](const auto &filter) { return filter->negate(); }); + return OringFilter::make(kind(), std::move(filters)); +} + +bool AndingFilter::is_tautology() const { return _subfilters.empty(); } + +bool AndingFilter::is_contradiction() const { return false; } + +Filters AndingFilter::disjuncts() const { + Filters filters; + filters.push_back(copy()); + return filters; +} + +Filters AndingFilter::conjuncts() const { + Filters filters; + std::transform(_subfilters.begin(), _subfilters.end(), + std::back_inserter(filters), + [](const auto &filter) { return filter->copy(); }); + return filters; +} + +std::ostream &AndingFilter::print(std::ostream &os) const { + for (const auto &filter : _subfilters) { + os << *filter << "\\n"; + } + switch (kind()) { + case Kind::row: + os << "And"; + break; + case Kind::stats: + os << "StatsAnd"; + break; + case Kind::wait_condition: + os << "WaitConditionAnd"; + break; + } + return os << ": " << _subfilters.size(); +} diff --git a/src/AndingFilter.h b/src/AndingFilter.h new file mode 100644 index 0000000..3ad5042 --- /dev/null +++ b/src/AndingFilter.h @@ -0,0 +1,81 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef AndingFilter_h +#define AndingFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Filter.h" +#include "contact_fwd.h" +class Column; +class Row; + +class AndingFilter : public Filter { + struct Secret {}; + +public: + static std::unique_ptr make(Kind kind, Filters subfilters); + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + std::unique_ptr partialFilter( + std::function predicate) const override; + [[nodiscard]] std::optional stringValueRestrictionFor( + const std::string &column_name) const override; + [[nodiscard]] std::optional greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::optional leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::optional> valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + [[nodiscard]] bool is_tautology() const override; + [[nodiscard]] bool is_contradiction() const override; + [[nodiscard]] Filters disjuncts() const override; + [[nodiscard]] Filters conjuncts() const override; + + // NOTE: This is effectively private, but it can't be declared like this + // because of std::make_unique. + AndingFilter(Kind kind, Filters subfilters, Secret /*unused*/) + : Filter(kind), _subfilters(std::move(subfilters)) {} + +private: + Filters _subfilters; + + std::ostream &print(std::ostream &os) const override; +}; + +#endif // AndingFilter_h diff --git a/src/AtomicInt32PointerColumn.h b/src/AtomicInt32PointerColumn.h new file mode 100644 index 0000000..42fd34c --- /dev/null +++ b/src/AtomicInt32PointerColumn.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef AtomicInt32PointerColumn_h +#define AtomicInt32PointerColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "IntColumn.h" + +class AtomicInt32PointerColumn : public IntColumn { +public: + AtomicInt32PointerColumn(const std::string& name, + const std::string& description, + const std::atomic_int32_t* number) + : IntColumn(name, description, -1, -1, -1, 0), _number(number) {} + + int32_t getValue(Row /* row */, + const contact* /* auth_user */) const override { + return _number->load(); + } + +private: + const std::atomic_int32_t* const _number; +}; + +#endif // AtomicInt32PointerColumn_h diff --git a/src/AttributeListAsIntColumn.cc b/src/AttributeListAsIntColumn.cc new file mode 100644 index 0000000..d893170 --- /dev/null +++ b/src/AttributeListAsIntColumn.cc @@ -0,0 +1,103 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "AttributeListAsIntColumn.h" +#include +#include +#include +#include +#include +#include +#include "Filter.h" +#include "IntFilter.h" +#include "Logger.h" +#include "Row.h" +#include "strutil.h" + +namespace { +// see MODATTR_FOO in nagios/common.h +std::map known_attributes = { + {"notifications_enabled", 0}, {"active_checks_enabled", 1}, + {"passive_checks_enabled", 2}, {"event_handler_enabled", 3}, + {"flap_detection_enabled", 4}, {"failure_prediction_enabled", 5}, + {"performance_data_enabled", 6}, {"obsessive_handler_enabled", 7}, + {"event_handler_command", 8}, {"check_command", 9}, + {"normal_check_interval", 10}, {"retry_check_interval", 11}, + {"max_check_attempts", 12}, {"freshness_checks_enabled", 13}, + {"check_timeperiod", 14}, {"custom_variable", 15}, + {"notification_timeperiod", 16}}; + +using modified_atttibutes = std::bitset<32>; + +std::string refValueFor(const std::string &value, Logger *logger) { + if (isdigit(value[0]) != 0) { + return value; + } + + std::vector value_vec(value.begin(), value.end()); + value_vec.push_back('\0'); + char *scan = &value_vec[0]; + + modified_atttibutes values; + for (const char *t; (t = next_token(&scan, ',')) != nullptr;) { + auto it = known_attributes.find(t); + if (it == known_attributes.end()) { + Informational(logger) + << "Ignoring invalid value '" << t << "' for attribute list"; + continue; + } + values[it->second] = true; + } + return std::to_string(values.to_ulong()); +} +} // namespace + +std::unique_ptr AttributeListAsIntColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, + refValueFor(value, logger())); +} + +int32_t AttributeListAsIntColumn::getValue( + Row row, const contact * /*auth_user*/) const { + if (auto p = columnData(row)) { + return static_cast(*p); + } + return 0; +} + +std::vector AttributeListAsIntColumn::getAttributes( + Row row) const { + std::vector attributes; + if (auto p = columnData(row)) { + modified_atttibutes values(*p); + for (const auto &entry : known_attributes) { + if (values[entry.second]) { + attributes.push_back(entry.first); + } + } + } + return attributes; +} diff --git a/src/AttributeListAsIntColumn.h b/src/AttributeListAsIntColumn.h new file mode 100644 index 0000000..7041b6f --- /dev/null +++ b/src/AttributeListAsIntColumn.h @@ -0,0 +1,57 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef AttributeListAsIntColumn_h +#define AttributeListAsIntColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "Filter.h" +#include "IntColumn.h" +#include "contact_fwd.h" +#include "opids.h" +class Row; + +class AttributeListAsIntColumn : public IntColumn { +public: + AttributeListAsIntColumn(const std::string &name, + const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + int32_t getValue(Row row, const contact *auth_user) const override; + + [[nodiscard]] std::vector getAttributes(Row row) const; +}; + +#endif // AttributeListAsIntColumn_h diff --git a/src/AttributeListColumn.cc b/src/AttributeListColumn.cc new file mode 100644 index 0000000..e826451 --- /dev/null +++ b/src/AttributeListColumn.cc @@ -0,0 +1,41 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "AttributeListColumn.h" +#include +#include +#include "Filter.h" // IWYU pragma: keep +#include "Row.h" + +std::unique_ptr AttributeListColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return _int_view_column.createFilter(kind, relOp, value); +} + +std::vector AttributeListColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + return _int_view_column.getAttributes(row); +} diff --git a/src/AttributeListColumn.h b/src/AttributeListColumn.h new file mode 100644 index 0000000..6b19a2c --- /dev/null +++ b/src/AttributeListColumn.h @@ -0,0 +1,62 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef AttributeListColumn_h +#define AttributeListColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "AttributeListAsIntColumn.h" +#include "Filter.h" +#include "ListColumn.h" +#include "contact_fwd.h" +#include "opids.h" +class Row; + +class AttributeListColumn : public ListColumn { +public: + AttributeListColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _int_view_column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + AttributeListAsIntColumn _int_view_column; +}; + +#endif // AttributeListColumn_h diff --git a/src/BitMask.h b/src/BitMask.h new file mode 100644 index 0000000..9724a99 --- /dev/null +++ b/src/BitMask.h @@ -0,0 +1,99 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2017 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef BitMask_h +#define BitMask_h + +#include "config.h" // IWYU pragma: keep +#include + +namespace mk { +// Return the enumerator's value as a compile-time constant, see Scott Meyer's +// "Effective Modern C++", item 10. +template +constexpr auto toUType(Enum e) noexcept { + return static_cast>(e); +} + +// A marker trait which enables the bit mask operators +template +struct is_bit_mask { + static const bool value = false; +}; + +// A helper macro to make the use sites of the marker trait less verbose +#define IS_BIT_MASK(ENUM) \ + namespace mk { \ + template <> \ + struct is_bit_mask { \ + static const bool value = true; \ + }; \ + } + +// A helper template to make template definitions a bit shorter +template +constexpr bool is_bit_mask_v = is_bit_mask::value; +} // namespace mk + +template >> +inline constexpr Enum operator&(Enum x, Enum y) { + return x &= y; +} + +template >> +inline constexpr Enum operator|(Enum x, Enum y) { + return x |= y; +} + +template >> +inline constexpr Enum operator^(Enum x, Enum y) { + return x ^= y; +} + +template >> +inline constexpr Enum operator~(Enum x) { + return Enum(~mk::toUType(x)); +} + +template >> +inline Enum &operator|=(Enum &x, Enum y) { + return x = Enum(mk::toUType(x) | mk::toUType(y)); +} + +template >> +inline const Enum &operator&=(Enum &x, Enum y) { + return x = Enum(mk::toUType(x) & mk::toUType(y)); +} + +template >> +inline Enum &operator^=(Enum &x, Enum y) { + return x = Enum(mk::toUType(x) ^ mk::toUType(y)); +} + +template >> +inline bool is_empty_bit_mask(Enum x) { + return x == Enum(0); +} + +#endif // BitMask_h diff --git a/src/BlobColumn.cc b/src/BlobColumn.cc new file mode 100644 index 0000000..8e5ac49 --- /dev/null +++ b/src/BlobColumn.cc @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "BlobColumn.h" +#include +#include "Renderer.h" +#include "Row.h" + +void BlobColumn::output(Row row, RowRenderer& r, const contact* /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + if (std::unique_ptr> blob = getValue(row)) { + r.output(*blob); + } else { + r.output(Null()); + } +} + +std::unique_ptr BlobColumn::createFilter( + Filter::Kind /*unused*/, RelationalOperator /*unused*/, + const std::string& /*unused*/) const { + throw std::runtime_error("filtering on blob column '" + name() + + "' not supported"); +} + +std::unique_ptr BlobColumn::createAggregator( + AggregationFactory /*factory*/) const { + throw std::runtime_error("aggregating on blob column '" + name() + + "' not supported"); +} diff --git a/src/BlobColumn.h b/src/BlobColumn.h new file mode 100644 index 0000000..f60ca9c --- /dev/null +++ b/src/BlobColumn.h @@ -0,0 +1,65 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef BlobColumn_h +#define BlobColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class BlobColumn : public Column { +public: + BlobColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset) + : Column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] ColumnType type() const override { return ColumnType::blob; } + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; + + [[nodiscard]] virtual std::unique_ptr> getValue( + Row row) const = 0; +}; + +#endif // BlobColumn_h diff --git a/src/ChronoUtils.h b/src/ChronoUtils.h new file mode 100644 index 0000000..0b0b13e --- /dev/null +++ b/src/ChronoUtils.h @@ -0,0 +1,142 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ChronoUtils_h +#define ChronoUtils_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include + +using minutes_d = std::chrono::duration>; + +inline double elapsed_ms_since(std::chrono::steady_clock::time_point then) { + return std::chrono::duration_cast< + std::chrono::duration>( + std::chrono::steady_clock::now() - then) + .count(); +} + +inline tm to_tm(std::chrono::system_clock::time_point tp) { + time_t t = std::chrono::system_clock::to_time_t(tp); + struct tm ret; +// NOTE: A brilliant example of how to make a simple API function a total +// chaos follows... +#if defined(__STDC_LIB_EXT1__) + // C11 function, only guaranteed to be available when a + // #define __STDC_WANT_LIB_EXT1_ 1 + // is done before including . Signature: + // struct tm *localtime_s(const time_t *restrict timer, + // struct tm *restrict result) + localtime_s(&t, &ret); +#elif defined(__WIN32) + // Win32 variant, it keeps us entertained with swapped parameters and a + // different return value, yay! Signature: + // errno_t localtime_s(struct tm* _tm, const time_t *time) + // We have to de-confuse cppcheck: + // cppcheck-suppress uninitvar + localtime_s(&ret, &t); +#else + // POSIX.1-2008 variant, available under MinGW64 only under obscure + // circumstances, so better avoid it there. Signature: + // struct tm *localtime_r(const time_t *restrict timer, + // struct tm *restrict result); + localtime_r(&t, &ret); +#endif + // Reason: see Win32 section above + // cppcheck-suppress uninitvar + return ret; +} + +inline std::chrono::system_clock::time_point from_tm(tm tp) { + return std::chrono::system_clock::from_time_t(mktime(&tp)); +} + +template +inline timeval to_timeval(std::chrono::duration dur) { + timeval tv; + // NOTE: The static_casts below are needed to avoid warning on e.g. some + // 32bit platforms, because the underlying types might be larger than the + // timeval fields. We can't use the correct POSIX types time_t and + // suseconds_t because of the broken MinGW cross compiler, so we revert to + // decltype. + tv.tv_sec = static_cast( + std::chrono::duration_cast(dur).count()); + tv.tv_usec = static_cast( + std::chrono::duration_cast( + dur % std::chrono::seconds(1)) + .count()); + return tv; +} + +inline std::chrono::system_clock::time_point from_timeval(const timeval &tv) { + return std::chrono::system_clock::time_point( + std::chrono::seconds(tv.tv_sec) + + std::chrono::microseconds(tv.tv_usec)); +} + +inline std::chrono::system_clock::time_point parse_time_t( + const std::string &str) { + return std::chrono::system_clock::from_time_t(atoi(str.c_str())); +} + +template +typename Dur::rep time_point_part(std::chrono::system_clock::time_point &tp) { + return std::chrono::duration_cast(tp.time_since_epoch() % Dur(1000)) + .count(); +} + +class FormattedTimePoint { +public: + explicit FormattedTimePoint(std::chrono::system_clock::time_point tp, + std::string format = default_format) + : _tp(tp), _format(std::move(format)) {} + explicit FormattedTimePoint(time_t t, std::string format = default_format) + : _tp(std::chrono::system_clock::from_time_t(t)) + , _format(std::move(format)) {} + + friend std::ostream &operator<<(std::ostream &os, + const FormattedTimePoint &f) { + tm local = to_tm(f._tp); + return os << std::put_time(&local, f._format.c_str()); + } + +private: + std::chrono::system_clock::time_point _tp; + std::string _format; + + // NOTE: In a perfect world we would simply use "%F %T" below, but the "%F" + // format is a C99 addition, and the "%T" format is part of The Single Unix + // Specification. Both formats should be available in any C++11-compliant + // compiler, but the MinGW cross compiler doesn't get this right. So let's + // use their ancient expansions... + static constexpr auto default_format = "%Y-%m-%d %H:%M:%S"; +}; + +#endif // ChronoUtils_h diff --git a/src/ClientQueue.cc b/src/ClientQueue.cc new file mode 100644 index 0000000..b76e836 --- /dev/null +++ b/src/ClientQueue.cc @@ -0,0 +1,64 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ClientQueue.h" +#include +#include + +ClientQueue::ClientQueue() : _should_terminate(false) {} + +ClientQueue::~ClientQueue() { + std::for_each(_queue.begin(), _queue.end(), close); +} + +void ClientQueue::addConnection(int fd) { + { + std::lock_guard lg(_mutex); + _queue.push_back(fd); + } + _cond.notify_one(); +} + +int ClientQueue::popConnection() { + std::unique_lock ul(_mutex); + while (_queue.empty() && !_should_terminate) { + _cond.wait(ul); + } + if (_queue.empty()) { + return -1; + } + int fd = _queue.front(); + _queue.pop_front(); + return fd; +} + +// Note: What we *really* want here is the functionality of +// notify_all_at_thread_exit. +void ClientQueue::terminate() { + { + std::lock_guard lg(_mutex); + _should_terminate = true; + } + _cond.notify_all(); +} diff --git a/src/ClientQueue.h b/src/ClientQueue.h new file mode 100644 index 0000000..5acf4ad --- /dev/null +++ b/src/ClientQueue.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ClientQueue_h +#define ClientQueue_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include + +class ClientQueue { +public: + ClientQueue(); + ~ClientQueue(); + void addConnection(int fd); + int popConnection(); + void terminate(); + +private: + // The mutext protects _queue and _should_terminate, and it works together + // with the condition variable. + std::mutex _mutex; + std::deque _queue; + bool _should_terminate; + std::condition_variable _cond; +}; + +#endif // ClientQueue_h diff --git a/src/Column.cc b/src/Column.cc new file mode 100644 index 0000000..7338e62 --- /dev/null +++ b/src/Column.cc @@ -0,0 +1,57 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Column.h" +#include +#include "Logger.h" + +Column::Column(std::string name, std::string description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset) + : _logger(Logger::getLogger("cmk.livestatus")) + , _name(std::move(name)) + , _description(std::move(description)) + , _indirect_offset(indirect_offset) + , _extra_offset(extra_offset) + , _extra_extra_offset(extra_extra_offset) + , _offset(offset) {} + +namespace { +const void *add(const void *data, int offset) { + return (data == nullptr || offset < 0) ? data + : offset_cast(data, offset); +} + +const void *shift(const void *data, int offset) { + return (data == nullptr || offset < 0) + ? data + : *offset_cast(data, offset); +} +} // namespace + +const void *Column::shiftPointer(Row row) const { + return add(shift(shift(shift(row.rawData(), _indirect_offset), + _extra_offset), + _extra_extra_offset), + _offset); +} diff --git a/src/Column.h b/src/Column.h new file mode 100644 index 0000000..b9c67e3 --- /dev/null +++ b/src/Column.h @@ -0,0 +1,95 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Column_h +#define Column_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include "Filter.h" +#include "Row.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregation; +class Aggregator; +class Logger; +class RowRenderer; + +template +const T *offset_cast(const void *ptr, size_t offset) { + // cppcheck is too dumb to see that this is just pointer arithmetic... :-/ + // cppcheck-suppress invalidPointerCast + return reinterpret_cast(reinterpret_cast(ptr) + + offset); +} + +enum class ColumnType { int_, double_, string, list, time, dict, blob, null }; + +using AggregationFactory = std::function()>; + +class Column { +public: + Column(std::string name, std::string description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset); + virtual ~Column() = default; + + [[nodiscard]] std::string name() const { return _name; } + [[nodiscard]] std::string description() const { return _description; } + + template + [[nodiscard]] const T *columnData(Row row) const { + return static_cast(shiftPointer(row)); + } + + [[nodiscard]] virtual ColumnType type() const = 0; + + virtual void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const = 0; + + [[nodiscard]] virtual std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const = 0; + + [[nodiscard]] virtual std::unique_ptr createAggregator( + AggregationFactory factory) const = 0; + + [[nodiscard]] Logger *logger() const { return _logger; } + +private: + Logger *const _logger; + std::string _name; + std::string _description; + int _indirect_offset; + int _extra_offset; + int _extra_extra_offset; + int _offset; + + [[nodiscard]] const void *shiftPointer(Row row) const; +}; + +#endif // Column_h diff --git a/src/ColumnFilter.cc b/src/ColumnFilter.cc new file mode 100644 index 0000000..858464f --- /dev/null +++ b/src/ColumnFilter.cc @@ -0,0 +1,51 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ColumnFilter.h" +#include "AndingFilter.h" + +std::unique_ptr ColumnFilter::partialFilter( + std::function predicate) const { + return predicate(_column) ? copy() : AndingFilter::make(kind(), Filters()); +} + +bool ColumnFilter::is_tautology() const { return false; } + +bool ColumnFilter::is_contradiction() const { return false; } + +Filters ColumnFilter::disjuncts() const { + Filters filters; + filters.push_back(copy()); + return filters; +} + +Filters ColumnFilter::conjuncts() const { + Filters filters; + filters.push_back(copy()); + return filters; +} + +std::ostream &ColumnFilter::print(std::ostream &os) const { + return os << "Filter: " << columnName() << " " << oper() << " " << value(); +} diff --git a/src/ColumnFilter.h b/src/ColumnFilter.h new file mode 100644 index 0000000..d9ee070 --- /dev/null +++ b/src/ColumnFilter.h @@ -0,0 +1,64 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ColumnFilter_h +#define ColumnFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "opids.h" + +class ColumnFilter : public Filter { +public: + ColumnFilter(Kind kind, const Column &column, RelationalOperator relOp, + std::string value) + : Filter(kind) + , _column(column) + , _relOp(relOp) + , _value(std::move(value)) {} + [[nodiscard]] std::string columnName() const { return _column.name(); } + [[nodiscard]] RelationalOperator oper() const { return _relOp; } + [[nodiscard]] std::string value() const { return _value; } + std::unique_ptr partialFilter( + std::function predicate) const override; + [[nodiscard]] bool is_tautology() const override; + [[nodiscard]] bool is_contradiction() const override; + [[nodiscard]] Filters disjuncts() const override; + [[nodiscard]] Filters conjuncts() const override; + +private: + const Column &_column; + const RelationalOperator _relOp; + const std::string _value; + + std::ostream &print(std::ostream &os) const override; +}; + +#endif // ColumnFilter_h diff --git a/src/ColumnsColumn.cc b/src/ColumnsColumn.cc new file mode 100644 index 0000000..7550838 --- /dev/null +++ b/src/ColumnsColumn.cc @@ -0,0 +1,35 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ColumnsColumn.h" +#include "Row.h" +#include "TableColumns.h" +class Column; + +std::string ColumnsColumn::getValue(Row row) const { + if (auto p = columnData(row)) { + return _table_columns.getValue(p, _colcol); + } + return ""; +} diff --git a/src/ColumnsColumn.h b/src/ColumnsColumn.h new file mode 100644 index 0000000..6eae721 --- /dev/null +++ b/src/ColumnsColumn.h @@ -0,0 +1,52 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ColumnsColumn_h +#define ColumnsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "StringColumn.h" +class Row; +class TableColumns; + +class ColumnsColumn : public StringColumn { +public: + enum class Type { table, name, description, type }; + + ColumnsColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset, Type colcol, const TableColumns &tablecols) + : StringColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _colcol(colcol) + , _table_columns(tablecols) {} + [[nodiscard]] std::string getValue(Row row) const override; + +private: + const Type _colcol; + const TableColumns &_table_columns; +}; + +#endif // ColumnsColumn_h diff --git a/src/CommentColumn.cc b/src/CommentColumn.cc new file mode 100644 index 0000000..4ac4399 --- /dev/null +++ b/src/CommentColumn.cc @@ -0,0 +1,76 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CommentColumn.h" +#include +#include +#include +#include +#include "MonitoringCore.h" +#include "Renderer.h" +#include "Row.h" +#include "nagios.h" + +void CommentColumn::output(Row row, RowRenderer &r, + const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + ListRenderer l(r); + for (const auto &comment : comments_for_row(row)) { + if (_with_info) { + SublistRenderer s(l); + s.output(comment._id); + s.output(comment._author); + s.output(comment._comment); + if (_with_extra_info) { + s.output(comment._entry_type); + s.output(comment._entry_time); + } + } else { + l.output(comment._id); + } + } +} + +std::vector CommentColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + std::vector ids; + auto comments = comments_for_row(row); + std::transform( + comments.begin(), comments.end(), std::back_inserter(ids), + [](const auto &comment) { return std::to_string(comment._id); }); + return ids; +} + +std::vector CommentColumn::comments_for_row(Row row) const { + if (auto data = columnData(row)) { + return _is_service + ? _mc->comments_for_service( + reinterpret_cast( + data)) + : _mc->comments_for_host( + reinterpret_cast(data)); + } + return {}; +} diff --git a/src/CommentColumn.h b/src/CommentColumn.h new file mode 100644 index 0000000..5f3207e --- /dev/null +++ b/src/CommentColumn.h @@ -0,0 +1,68 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CommentColumn_h +#define CommentColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +struct CommentData; +class MonitoringCore; +class RowRenderer; +class Row; + +class CommentColumn : public ListColumn { +public: + CommentColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset, MonitoringCore *mc, bool is_service, + bool with_info, bool with_extra_info) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _is_service(is_service) + , _with_info(with_info) + , _with_extra_info(with_extra_info) {} + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *_mc; + bool _is_service; + bool _with_info; + bool _with_extra_info; + + [[nodiscard]] std::vector comments_for_row(Row row) const; +}; + +#endif // CommentColumn_h diff --git a/src/ContactGroupsColumn.cc b/src/ContactGroupsColumn.cc new file mode 100644 index 0000000..c66e898 --- /dev/null +++ b/src/ContactGroupsColumn.cc @@ -0,0 +1,54 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ContactGroupsColumn.h" +#include "Row.h" + +#ifdef CMC +#include "ContactList.h" +#include "Object.h" +#include "cmc.h" +#else +#include "nagios.h" +#endif + +std::vector ContactGroupsColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + std::vector names; +#ifdef CMC + if (auto object = columnData(row)) { + for (const auto &name : object->_contact_list->groupNames()) { + names.push_back(name); + } + } +#else + if (auto p = columnData(row)) { + for (auto cgm = *p; cgm != nullptr; cgm = cgm->next) { + names.emplace_back(cgm->group_ptr->group_name); + } + } +#endif + return names; +} diff --git a/src/ContactGroupsColumn.h b/src/ContactGroupsColumn.h new file mode 100644 index 0000000..48cf734 --- /dev/null +++ b/src/ContactGroupsColumn.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ContactGroupsColumn_h +#define ContactGroupsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class Row; + +class ContactGroupsColumn : public ListColumn { +public: + ContactGroupsColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; +}; + +#endif // ContactGroupsColumn_h diff --git a/src/ContactGroupsMemberColumn.cc b/src/ContactGroupsMemberColumn.cc new file mode 100644 index 0000000..31918f6 --- /dev/null +++ b/src/ContactGroupsMemberColumn.cc @@ -0,0 +1,51 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ContactGroupsMemberColumn.h" +#include "Row.h" + +#ifdef CMC +#include "ContactGroup.h" +#else +#include "nagios.h" +#endif + +std::vector ContactGroupsMemberColumn::getValue( + Row row, const contact* /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { +#ifdef CMC + if (auto cg = columnData(row)) { + return cg->contactNames(); + } + return {}; +#else + std::vector names; + if (auto cg = columnData(row)) { + for (auto cm = cg->members; cm != nullptr; cm = cm->next) { + names.emplace_back(cm->contact_ptr->name); + } + } + return names; +#endif +} diff --git a/src/ContactGroupsMemberColumn.h b/src/ContactGroupsMemberColumn.h new file mode 100644 index 0000000..cbcfe5c --- /dev/null +++ b/src/ContactGroupsMemberColumn.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ContactGroupsMemberColumn_h +#define ContactGroupsMemberColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class Row; + +class ContactGroupsMemberColumn : public ListColumn { +public: + ContactGroupsMemberColumn(const std::string& name, + const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + std::vector getValue( + Row row, const contact* auth_user, + std::chrono::seconds timezone_offset) const override; +}; + +#endif // ContactGroupsMemberColumn_h diff --git a/src/CountAggregator.cc b/src/CountAggregator.cc new file mode 100644 index 0000000..a7dd3cf --- /dev/null +++ b/src/CountAggregator.cc @@ -0,0 +1,37 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CountAggregator.h" +#include "Filter.h" +#include "Renderer.h" +#include "Row.h" + +void CountAggregator::consume(Row row, const contact* auth_user, + std::chrono::seconds timezone_offset) { + if (_filter->accepts(row, auth_user, timezone_offset)) { + _count++; + } +} + +void CountAggregator::output(RowRenderer& r) const { r.output(_count); } diff --git a/src/CountAggregator.h b/src/CountAggregator.h new file mode 100644 index 0000000..f9b0148 --- /dev/null +++ b/src/CountAggregator.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CountAggregator_h +#define CountAggregator_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "Aggregator.h" +#include "contact_fwd.h" +class Filter; +class Row; +class RowRenderer; + +class CountAggregator : public Aggregator { +public: + explicit CountAggregator(const Filter *filter) + : _filter(filter), _count(0) {} + void consume(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) override; + void output(RowRenderer &r) const override; + +private: + const Filter *const _filter; + std::uint32_t _count; +}; + +#endif // CountAggregator_h diff --git a/src/CustomTimeperiodColumn.cc b/src/CustomTimeperiodColumn.cc new file mode 100644 index 0000000..2acdad4 --- /dev/null +++ b/src/CustomTimeperiodColumn.cc @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CustomTimeperiodColumn.h" +#include "Row.h" +#include "TimeperiodsCache.h" + +extern TimeperiodsCache *g_timeperiods_cache; + +// Get the name of a timeperiod from a custom variable and lookup the current +// state of that period +int32_t CustomTimeperiodColumn::getValue( + Row row, const contact * /* auth_user */) const { + for (customvariablesmember *cvm = getCVM(row); cvm != nullptr; + cvm = cvm->next) { + if (cvm->variable_name == _varname) { + return static_cast( + g_timeperiods_cache->inTimeperiod(cvm->variable_value)); + } + } + return 1; // assume 24X7 +} + +customvariablesmember *CustomTimeperiodColumn::getCVM(Row row) const { + if (auto p = columnData(row)) { + return *p; + } + return nullptr; +} diff --git a/src/CustomTimeperiodColumn.h b/src/CustomTimeperiodColumn.h new file mode 100644 index 0000000..589278a --- /dev/null +++ b/src/CustomTimeperiodColumn.h @@ -0,0 +1,53 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CustomTimeperiodColumn_h +#define CustomTimeperiodColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "IntColumn.h" +#include "nagios.h" +class Row; + +class CustomTimeperiodColumn : public IntColumn { +public: + CustomTimeperiodColumn(const std::string &name, + const std::string &description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset, + std::string varname) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _varname(std::move(varname)) {} + int32_t getValue(Row row, const contact *auth_user) const override; + +private: + std::string _varname; + + [[nodiscard]] customvariablesmember *getCVM(Row row) const; +}; + +#endif // CustomTimeperiodColumn_h diff --git a/src/CustomVarsDictColumn.cc b/src/CustomVarsDictColumn.cc new file mode 100644 index 0000000..3a7a998 --- /dev/null +++ b/src/CustomVarsDictColumn.cc @@ -0,0 +1,77 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CustomVarsDictColumn.h" +#include +#include +#include "CustomVarsDictFilter.h" +#include "Filter.h" +#include "Renderer.h" +#include "Row.h" +class Aggregator; + +#ifdef CMC +#include "Object.h" +#include "cmc.h" +#else +#include "nagios.h" +#endif + +void CustomVarsDictColumn::output( + Row row, RowRenderer &r, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + DictRenderer d(r); + for (const auto &it : getValue(row)) { + d.output(it.first, it.second); + } +} + +std::unique_ptr CustomVarsDictColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, value); +} + +std::unique_ptr CustomVarsDictColumn::createAggregator( + AggregationFactory /*factory*/) const { + throw std::runtime_error("aggregating on dictionary column '" + name() + + "' not supported"); +} + +std::unordered_map CustomVarsDictColumn::getValue( + Row row) const { + std::unordered_map dict; +#ifdef CMC + if (auto *object = columnData(row)) { + return object->customAttributes(); + } +#else + if (auto p = columnData(row)) { + for (auto cvm = *p; cvm != nullptr; cvm = cvm->next) { + dict.emplace(cvm->variable_name, cvm->variable_value); + } + } +#endif + return dict; +} diff --git a/src/CustomVarsDictColumn.h b/src/CustomVarsDictColumn.h new file mode 100644 index 0000000..a711d99 --- /dev/null +++ b/src/CustomVarsDictColumn.h @@ -0,0 +1,66 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CustomVarsDictColumn_h +#define CustomVarsDictColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class CustomVarsDictColumn : public Column { +public: + CustomVarsDictColumn(std::string name, std::string description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : Column(std::move(name), std::move(description), indirect_offset, + extra_offset, extra_extra_offset, offset) {} + + [[nodiscard]] ColumnType type() const override { return ColumnType::dict; }; + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; + + [[nodiscard]] std::unordered_map getValue( + Row row) const; +}; + +#endif // CustomVarsDictColumn_h diff --git a/src/CustomVarsDictFilter.cc b/src/CustomVarsDictFilter.cc new file mode 100644 index 0000000..89b67dd --- /dev/null +++ b/src/CustomVarsDictFilter.cc @@ -0,0 +1,87 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CustomVarsDictFilter.h" +#include +#include +#include +#include "CustomVarsDictColumn.h" +#include "Filter.h" +#include "RegExp.h" +#include "Row.h" +#include "StringUtils.h" + +CustomVarsDictFilter::CustomVarsDictFilter(Kind kind, + const CustomVarsDictColumn &column, + RelationalOperator relOp, + const std::string &value) + : ColumnFilter(kind, column, relOp, value), _column(column) { + // Filter for custom_variables: + // Filter: custom_variables = PATH /hirni.mk + // The variable name is part of the value and separated with spaces + std::tie(_ref_varname, _ref_string) = mk::nextField(value); + _ref_string = mk::lstrip(_ref_string); + _regExp = makeRegExpFor(oper(), _ref_string); +} + +bool CustomVarsDictFilter::accepts( + Row row, const contact * /* auth_user */, + std::chrono::seconds /* timezone_offset */) const { + auto cvm = _column.getValue(row); + auto it = cvm.find(_ref_varname); + auto act_string = it == cvm.end() ? "" : it->second; + switch (oper()) { + case RelationalOperator::equal: + case RelationalOperator::equal_icase: + return _regExp->match(act_string); + case RelationalOperator::not_equal: + case RelationalOperator::not_equal_icase: + return !_regExp->match(act_string); + case RelationalOperator::matches: + case RelationalOperator::matches_icase: + return _regExp->search(act_string); + case RelationalOperator::doesnt_match: + case RelationalOperator::doesnt_match_icase: + return !_regExp->search(act_string); + // FIXME: The cases below are nonsense for UTF-8... + case RelationalOperator::less: + return act_string < _ref_string; + case RelationalOperator::greater_or_equal: + return act_string >= _ref_string; + case RelationalOperator::greater: + return act_string > _ref_string; + case RelationalOperator::less_or_equal: + return act_string <= _ref_string; + } + return false; // unreachable +} + +std::unique_ptr CustomVarsDictFilter::copy() const { + return std::make_unique(*this); +} + +std::unique_ptr CustomVarsDictFilter::negate() const { + return std::make_unique( + kind(), _column, negateRelationalOperator(oper()), value()); +} diff --git a/src/CustomVarsDictFilter.h b/src/CustomVarsDictFilter.h new file mode 100644 index 0000000..c73aba8 --- /dev/null +++ b/src/CustomVarsDictFilter.h @@ -0,0 +1,56 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CustomVarsDictFilter_h +#define CustomVarsDictFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ColumnFilter.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class CustomVarsDictColumn; +class RegExp; +class Row; + +class CustomVarsDictFilter : public ColumnFilter { +public: + CustomVarsDictFilter(Kind kind, const CustomVarsDictColumn &column, + RelationalOperator relOp, const std::string &value); + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + +private: + const CustomVarsDictColumn &_column; + std::shared_ptr _regExp; + std::string _ref_string; + std::string _ref_varname; +}; + +#endif // CustomVarsDictFilter_h diff --git a/src/CustomVarsExplicitColumn.cc b/src/CustomVarsExplicitColumn.cc new file mode 100644 index 0000000..82d69af --- /dev/null +++ b/src/CustomVarsExplicitColumn.cc @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CustomVarsExplicitColumn.h" +#include "Row.h" + +std::string CustomVarsExplicitColumn::getValue(Row row) const { + for (customvariablesmember *cvm = getCVM(row); cvm != nullptr; + cvm = cvm->next) { + if (cvm->variable_name == _varname) { + return cvm->variable_value; + } + } + return ""; +} + +customvariablesmember *CustomVarsExplicitColumn::getCVM(Row row) const { + if (auto p = columnData(row)) { + return *p; + } + return nullptr; +} diff --git a/src/CustomVarsExplicitColumn.h b/src/CustomVarsExplicitColumn.h new file mode 100644 index 0000000..bc708e7 --- /dev/null +++ b/src/CustomVarsExplicitColumn.h @@ -0,0 +1,52 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CustomVarsExplicitColumn_h +#define CustomVarsExplicitColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "StringColumn.h" +#include "nagios.h" +class Row; + +class CustomVarsExplicitColumn : public StringColumn { +public: + CustomVarsExplicitColumn(const std::string &name, + const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, + const char *varname) + : StringColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _varname(varname) {} + [[nodiscard]] std::string getValue(Row row) const override; + +private: + std::string _varname; + + [[nodiscard]] customvariablesmember *getCVM(Row row) const; +}; + +#endif // CustomVarsExplicitColumn_h diff --git a/src/CustomVarsNamesColumn.cc b/src/CustomVarsNamesColumn.cc new file mode 100644 index 0000000..160632b --- /dev/null +++ b/src/CustomVarsNamesColumn.cc @@ -0,0 +1,56 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CustomVarsNamesColumn.h" +#include "Row.h" + +#ifdef CMC +#include +#include +#include +#include "Object.h" +#include "cmc.h" +#else +#include "nagios.h" +#endif + +std::vector CustomVarsNamesColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + std::vector names; +#ifdef CMC + if (auto *object = columnData(row)) { + auto attrs = object->customAttributes(); + std::transform(attrs.begin(), attrs.end(), std::back_inserter(names), + [](const auto &entry) { return entry.first; }); + } +#else + if (auto p = columnData(row)) { + for (auto cvm = *p; cvm != nullptr; cvm = cvm->next) { + names.emplace_back(cvm->variable_name); + } + } +#endif + return names; +} diff --git a/src/CustomVarsNamesColumn.h b/src/CustomVarsNamesColumn.h new file mode 100644 index 0000000..c4322e9 --- /dev/null +++ b/src/CustomVarsNamesColumn.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CustomVarsNamesColumn_h +#define CustomVarsNamesColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class Row; + +class CustomVarsNamesColumn : public ListColumn { +public: + CustomVarsNamesColumn(const std::string &name, + const std::string &description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; +}; + +#endif // CustomVarsNamesColumn_h diff --git a/src/CustomVarsValuesColumn.cc b/src/CustomVarsValuesColumn.cc new file mode 100644 index 0000000..3a0a773 --- /dev/null +++ b/src/CustomVarsValuesColumn.cc @@ -0,0 +1,56 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "CustomVarsValuesColumn.h" +#include "Row.h" + +#ifdef CMC +#include +#include +#include +#include "Object.h" +#include "cmc.h" +#else +#include "nagios.h" +#endif + +std::vector CustomVarsValuesColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + std::vector values; +#ifdef CMC + if (auto *object = columnData(row)) { + auto attrs = object->customAttributes(); + std::transform(attrs.begin(), attrs.end(), std::back_inserter(values), + [](const auto &entry) { return entry.second; }); + } +#else + if (auto p = columnData(row)) { + for (auto cvm = *p; cvm != nullptr; cvm = cvm->next) { + values.emplace_back(cvm->variable_value); + } + } +#endif + return values; +} diff --git a/src/CustomVarsValuesColumn.h b/src/CustomVarsValuesColumn.h new file mode 100644 index 0000000..6796e19 --- /dev/null +++ b/src/CustomVarsValuesColumn.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef CustomVarsValuesColumn_h +#define CustomVarsValuesColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class Row; + +class CustomVarsValuesColumn : public ListColumn { +public: + CustomVarsValuesColumn(const std::string &name, + const std::string &description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; +}; + +#endif // CustomVarsValuesColumn_h diff --git a/src/DoubleAggregator.h b/src/DoubleAggregator.h new file mode 100644 index 0000000..45649e7 --- /dev/null +++ b/src/DoubleAggregator.h @@ -0,0 +1,56 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DoubleAggregator_h +#define DoubleAggregator_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Aggregator.h" +#include "DoubleColumn.h" +#include "contact_fwd.h" +class Row; +class RowRenderer; + +class DoubleAggregator : public Aggregator { +public: + DoubleAggregator(const AggregationFactory &factory, + const DoubleColumn *column) + : _aggregation(factory()), _column(column) {} + + void consume(Row row, const contact * /*contact*/, + std::chrono::seconds /*timezone_offset*/) override { + _aggregation->update(_column->getValue(row)); + } + + void output(RowRenderer &r) const override { + r.output(_aggregation->value()); + } + +private: + std::unique_ptr _aggregation; + const DoubleColumn *const _column; +}; + +#endif // DoubleAggregator_h diff --git a/src/DoubleColumn.cc b/src/DoubleColumn.cc new file mode 100644 index 0000000..7a1d155 --- /dev/null +++ b/src/DoubleColumn.cc @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DoubleColumn.h" +#include "Aggregator.h" +#include "DoubleAggregator.h" +#include "DoubleFilter.h" +#include "Filter.h" +#include "Renderer.h" +#include "Row.h" + +void DoubleColumn::output(Row row, RowRenderer &r, + const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + r.output(getValue(row)); +} + +std::unique_ptr DoubleColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, value); +} + +std::unique_ptr DoubleColumn::createAggregator( + AggregationFactory factory) const { + return std::make_unique(factory, this); +} diff --git a/src/DoubleColumn.h b/src/DoubleColumn.h new file mode 100644 index 0000000..4569625 --- /dev/null +++ b/src/DoubleColumn.h @@ -0,0 +1,60 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DoubleColumn_h +#define DoubleColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class DoubleColumn : public Column { +public: + DoubleColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset) + : Column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + [[nodiscard]] virtual double getValue(Row row) const = 0; + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] ColumnType type() const override { + return ColumnType::double_; + } + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; +}; + +#endif // DoubleColumn_h diff --git a/src/DoubleFilter.cc b/src/DoubleFilter.cc new file mode 100644 index 0000000..d4eeeb8 --- /dev/null +++ b/src/DoubleFilter.cc @@ -0,0 +1,76 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DoubleFilter.h" +#include +#include +#include "DoubleColumn.h" +#include "Filter.h" +#include "Logger.h" +#include "Row.h" + +DoubleFilter::DoubleFilter(Kind kind, const DoubleColumn &column, + RelationalOperator relOp, const std::string &value) + : ColumnFilter(kind, column, relOp, value) + , _column(column) + , _ref_value(atof(value.c_str())) {} + +bool DoubleFilter::accepts(Row row, const contact * /* auth_user */, + std::chrono::seconds /* timezone_offset */) const { + double act_value = _column.getValue(row); + switch (oper()) { + case RelationalOperator::equal: + return act_value == _ref_value; + case RelationalOperator::not_equal: + return act_value != _ref_value; + case RelationalOperator::less: + return act_value < _ref_value; + case RelationalOperator::greater_or_equal: + return act_value >= _ref_value; + case RelationalOperator::greater: + return act_value > _ref_value; + case RelationalOperator::less_or_equal: + return act_value <= _ref_value; + case RelationalOperator::matches: + case RelationalOperator::doesnt_match: + case RelationalOperator::equal_icase: + case RelationalOperator::not_equal_icase: + case RelationalOperator::matches_icase: + case RelationalOperator::doesnt_match_icase: + Informational(_column.logger()) + << "Sorry. Operator " << oper() + << " for float columns not implemented."; + return false; + } + return false; // unreachable +} + +std::unique_ptr DoubleFilter::copy() const { + return std::make_unique(*this); +} + +std::unique_ptr DoubleFilter::negate() const { + return std::make_unique( + kind(), _column, negateRelationalOperator(oper()), value()); +} diff --git a/src/DoubleFilter.h b/src/DoubleFilter.h new file mode 100644 index 0000000..a7dbd40 --- /dev/null +++ b/src/DoubleFilter.h @@ -0,0 +1,53 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DoubleFilter_h +#define DoubleFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ColumnFilter.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class DoubleColumn; +class Row; + +class DoubleFilter : public ColumnFilter { +public: + DoubleFilter(Kind kind, const DoubleColumn &column, + RelationalOperator relOp, const std::string &value); + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + +private: + const DoubleColumn &_column; + const double _ref_value; +}; + +#endif // DoubleFilter_h diff --git a/src/DoublePointerColumn.h b/src/DoublePointerColumn.h new file mode 100644 index 0000000..fb49b23 --- /dev/null +++ b/src/DoublePointerColumn.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DoublePointerColumn_h +#define DoublePointerColumn_h + +#include "config.h" // IWYU pragma: keep +#include "DoubleColumn.h" + +class DoublePointerColumn : public DoubleColumn { +public: + DoublePointerColumn(const std::string &name, const std::string &description, + const double *number) + : DoubleColumn(name, description, -1, -1, -1, 0), _number(number) {} + + [[nodiscard]] double getValue(Row /*unused*/) const override { + return *_number; + } + +private: + const double *const _number; +}; + +#endif // DoublePointerColumn_h diff --git a/src/DowntimeColumn.cc b/src/DowntimeColumn.cc new file mode 100644 index 0000000..7f75bc0 --- /dev/null +++ b/src/DowntimeColumn.cc @@ -0,0 +1,70 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DowntimeColumn.h" +#include "MonitoringCore.h" +#include "Renderer.h" +#include "Row.h" + +#ifndef CMC +#include "nagios.h" +#endif + +void DowntimeColumn::output(Row row, RowRenderer &r, + const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + ListRenderer l(r); + for (const auto &downtime : downtimes_for_row(row)) { + if (_with_info) { + SublistRenderer s(l); + s.output(downtime._id); + s.output(downtime._author); + s.output(downtime._comment); + } else { + l.output(downtime._id); + } + } +} + +std::vector DowntimeColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + std::vector ids; + for (const auto &downtime : downtimes_for_row(row)) { + ids.push_back(std::to_string(downtime._id)); + } + return ids; +} + +std::vector DowntimeColumn::downtimes_for_row(Row row) const { + if (auto data = columnData(row)) { + return _is_service + ? _mc->downtimes_for_service( + reinterpret_cast( + data)) + : _mc->downtimes_for_host( + reinterpret_cast(data)); + } + return {}; +} diff --git a/src/DowntimeColumn.h b/src/DowntimeColumn.h new file mode 100644 index 0000000..c0a3ab0 --- /dev/null +++ b/src/DowntimeColumn.h @@ -0,0 +1,66 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DowntimeColumn_h +#define DowntimeColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +struct DowntimeData; +class MonitoringCore; +class Row; +class RowRenderer; + +class DowntimeColumn : public ListColumn { +public: + DowntimeColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, MonitoringCore *mc, + bool is_service, bool with_info) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _is_service(is_service) + , _with_info(with_info) {} + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *_mc; + bool _is_service; + bool _with_info; + + [[nodiscard]] std::vector downtimes_for_row(Row row) const; +}; + +#endif // DowntimeColumn_h diff --git a/src/DowntimeOrComment.cc b/src/DowntimeOrComment.cc new file mode 100644 index 0000000..32df461 --- /dev/null +++ b/src/DowntimeOrComment.cc @@ -0,0 +1,57 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DowntimeOrComment.h" + +DowntimeOrComment::DowntimeOrComment(nebstruct_downtime_struct *dt, + unsigned long id) + : _type(dt->downtime_type) + , _is_service(dt->service_description != nullptr) + , _host(find_host(dt->host_name)) + , _service(_is_service + ? find_service(dt->host_name, dt->service_description) + : nullptr) + , _entry_time(dt->entry_time) + , _author_name(dt->author_name) + , _comment(dt->comment_data) + , _id(id) {} + +DowntimeOrComment::~DowntimeOrComment() = default; + +Downtime::Downtime(nebstruct_downtime_struct *dt) + : DowntimeOrComment(dt, dt->downtime_id) + , _start_time(dt->start_time) + , _end_time(dt->end_time) + , _fixed(dt->fixed) + , _duration(static_cast(dt->duration)) + , _triggered_by(static_cast(dt->triggered_by)) {} + +Comment::Comment(nebstruct_comment_struct *co) + : DowntimeOrComment(reinterpret_cast(co), + co->comment_id) + , _expire_time(co->expire_time) + , _persistent(co->persistent) + , _source(co->source) + , _entry_type(co->entry_type) + , _expires(co->expires) {} diff --git a/src/DowntimeOrComment.h b/src/DowntimeOrComment.h new file mode 100644 index 0000000..c545829 --- /dev/null +++ b/src/DowntimeOrComment.h @@ -0,0 +1,119 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DowntimeOrComment_h +#define DowntimeOrComment_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "nagios.h" + +/* The structs for downtime and comment are so similar, that + we handle them with the same logic */ + +/* + typedef struct nebstruct_downtime_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int downtime_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + time_t start_time; + time_t end_time; + int fixed; + unsigned long duration; + unsigned long triggered_by; + unsigned long downtime_id; + + void *object_ptr; // not implemented yet + }nebstruct_downtime_data; + + typedef struct nebstruct_comment_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int comment_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + int persistent; + int source; + int entry_type; + int expires; + time_t expire_time; + unsigned long comment_id; + + void *object_ptr; // not implemented yet + }nebstruct_comment_data; + */ + +class DowntimeOrComment { +public: + int _type; + bool _is_service; + host *_host; + service *_service; + time_t _entry_time; + std::string _author_name; + std::string _comment; + unsigned long _id; + + DowntimeOrComment(nebstruct_downtime_struct *dt, unsigned long id); + virtual ~DowntimeOrComment(); +}; + +class Downtime : public DowntimeOrComment { +public: + time_t _start_time; + time_t _end_time; + int _fixed; + // TODO(sp): Wrong types, caused by TableDowntimes accessing it via + // OffsetIntColumn, should be unsigned long + int _duration; + int _triggered_by; + explicit Downtime(nebstruct_downtime_struct *dt); +}; + +class Comment : public DowntimeOrComment { +public: + time_t _expire_time; + int _persistent; + int _source; + int _entry_type; + int _expires; + explicit Comment(nebstruct_comment_struct *co); +}; + +#endif // DowntimeOrComment_h diff --git a/src/DowntimesOrComments.cc b/src/DowntimesOrComments.cc new file mode 100644 index 0000000..7aa44b2 --- /dev/null +++ b/src/DowntimesOrComments.cc @@ -0,0 +1,67 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DowntimesOrComments.h" +#include +#include "DowntimeOrComment.h" +#include "Logger.h" + +DowntimesOrComments::DowntimesOrComments() + : _logger(Logger::getLogger("cmk.livestatus")) {} + +void DowntimesOrComments::registerDowntime(nebstruct_downtime_data *data) { + unsigned long id = data->downtime_id; + switch (data->type) { + case NEBTYPE_DOWNTIME_ADD: + case NEBTYPE_DOWNTIME_LOAD: + _entries[id] = std::make_unique(data); + break; + case NEBTYPE_DOWNTIME_DELETE: + if (_entries.erase(id) == 0) { + Informational(_logger) + << "Cannot delete non-existing downtime " << id; + } + break; + default: + break; + } +} + +void DowntimesOrComments::registerComment(nebstruct_comment_data *data) { + unsigned long id = data->comment_id; + switch (data->type) { + case NEBTYPE_COMMENT_ADD: + case NEBTYPE_COMMENT_LOAD: + _entries[id] = std::make_unique(data); + break; + case NEBTYPE_COMMENT_DELETE: + if (_entries.erase(id) == 0) { + Informational(_logger) + << "Cannot delete non-existing comment " << id; + } + break; + default: + break; + } +} diff --git a/src/DowntimesOrComments.h b/src/DowntimesOrComments.h new file mode 100644 index 0000000..281a7ba --- /dev/null +++ b/src/DowntimesOrComments.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DowntimesOrComments_h +#define DowntimesOrComments_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "nagios.h" +class DowntimeOrComment; +class Logger; + +class DowntimesOrComments { +public: + DowntimesOrComments(); + void registerDowntime(nebstruct_downtime_data *data); + void registerComment(nebstruct_comment_data *data); + [[nodiscard]] auto begin() const { return _entries.cbegin(); } + [[nodiscard]] auto end() const { return _entries.cend(); } + +private: + std::map> _entries; + Logger *const _logger; +}; + +#endif // DowntimesOrComments_h diff --git a/src/DynamicColumn.cc b/src/DynamicColumn.cc new file mode 100644 index 0000000..fd1423f --- /dev/null +++ b/src/DynamicColumn.cc @@ -0,0 +1,40 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DynamicColumn.h" +#include + +DynamicColumn::DynamicColumn(std::string name, std::string description, + Logger *logger, int indirect_offset, + int extra_offset, int extra_extra_offset) + : _name(std::move(name)) + , _description(std::move(description)) + , _logger(logger) + , _indirect_offset(indirect_offset) + , _extra_offset(extra_offset) + , _extra_extra_offset(extra_extra_offset) {} + +DynamicColumn::~DynamicColumn() = default; + +std::string DynamicColumn::name() const { return _name; } diff --git a/src/DynamicColumn.h b/src/DynamicColumn.h new file mode 100644 index 0000000..4f106ca --- /dev/null +++ b/src/DynamicColumn.h @@ -0,0 +1,53 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DynamicColumn_h +#define DynamicColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +class Column; +class Logger; + +class DynamicColumn { +public: + DynamicColumn(std::string name, std::string description, Logger *logger, + int indirect_offset, int extra_offset, + int extra_extra_offset); + virtual ~DynamicColumn(); + [[nodiscard]] std::string name() const; + virtual std::unique_ptr createColumn( + const std::string &name, const std::string &arguments) = 0; + +protected: + const std::string _name; + const std::string _description; // Note: Currently unused! + Logger *const _logger; + const int _indirect_offset; + const int _extra_offset; + const int _extra_extra_offset; +}; + +#endif // DynamicColumn_h diff --git a/src/DynamicEventConsoleReplicationColumn.cc b/src/DynamicEventConsoleReplicationColumn.cc new file mode 100644 index 0000000..2e244c9 --- /dev/null +++ b/src/DynamicEventConsoleReplicationColumn.cc @@ -0,0 +1,95 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DynamicEventConsoleReplicationColumn.h" +#include +#include +#include +#include +#include +#include "BlobColumn.h" +#include "Column.h" +#include "EventConsoleConnection.h" +#include "Logger.h" +#include "MonitoringCore.h" +#include "Row.h" + +namespace { +class ECTableConnection : public EventConsoleConnection { +public: + ECTableConnection(MonitoringCore *mc, std::string command) + : EventConsoleConnection(mc->loggerLivestatus(), + mc->mkeventdSocketPath()) + , _command(std::move(command)) {} + [[nodiscard]] std::string getResult() const { return _result; } + +private: + void sendRequest(std::ostream &os) override { os << _command; } + void receiveReply(std::istream &is) override { std::getline(is, _result); } + + const std::string _command; + std::string _result; +}; + +class ReplicationColumn : public BlobColumn { +public: + ReplicationColumn(const std::string &name, const std::string &description, + std::string blob, int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : BlobColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _blob(std::move(blob)) {} + + [[nodiscard]] std::unique_ptr> getValue( + Row /* unused */) const override { + return std::make_unique>(_blob.begin(), _blob.end()); + }; + +private: + const std::string _blob; +}; +} // namespace + +DynamicEventConsoleReplicationColumn::DynamicEventConsoleReplicationColumn( + const std::string &name, const std::string &description, MonitoringCore *mc, + int indirect_offset, int extra_offset, int extra_extra_offset) + : DynamicColumn(name, description, mc->loggerLivestatus(), indirect_offset, + extra_offset, extra_extra_offset) + , _mc(mc) {} + +std::unique_ptr DynamicEventConsoleReplicationColumn::createColumn( + const std::string &name, const std::string &arguments) { + std::string result; + if (_mc->mkeventdEnabled()) { + try { + ECTableConnection ec(_mc, "REPLICATE " + arguments); + ec.run(); + result = ec.getResult(); + } catch (const std::runtime_error &err) { + Alert(_mc->loggerLivestatus()) << err.what(); + } + } + return std::make_unique(name, "replication value", + result, -1, -1, -1, 0); +} diff --git a/src/DynamicEventConsoleReplicationColumn.h b/src/DynamicEventConsoleReplicationColumn.h new file mode 100644 index 0000000..dc38aa4 --- /dev/null +++ b/src/DynamicEventConsoleReplicationColumn.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DynamicEventConsoleReplicationColumn_h +#define DynamicEventConsoleReplicationColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "DynamicColumn.h" +class Column; +class MonitoringCore; + +class DynamicEventConsoleReplicationColumn : public DynamicColumn { +public: + DynamicEventConsoleReplicationColumn(const std::string &name, + const std::string &description, + MonitoringCore *mc, + int indirect_offset, int extra_offset, + int extra_extra_offset); + + std::unique_ptr createColumn(const std::string &name, + const std::string &arguments) override; + +private: + MonitoringCore *_mc; +}; + +#endif // DynamicEventConsoleReplicationColumn_h diff --git a/src/DynamicLogwatchFileColumn.cc b/src/DynamicLogwatchFileColumn.cc new file mode 100644 index 0000000..21f2831 --- /dev/null +++ b/src/DynamicLogwatchFileColumn.cc @@ -0,0 +1,69 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "DynamicLogwatchFileColumn.h" +#include +#include "Column.h" +#include "HostFileColumn.h" +#include "MonitoringCore.h" + +namespace { +// Replace \\ with \ and \s with space +std::string unescape_filename(std::string filename) { + std::string filename_native; + bool quote_active = false; + for (auto c : filename) { + if (quote_active) { + if (c == 's') { + filename_native += ' '; + } else { + filename_native += c; + } + quote_active = false; + } else if (c == '\\') { + quote_active = true; + } else { + filename_native += c; + } + } + return filename_native; +} +} // namespace + +std::unique_ptr DynamicLogwatchFileColumn::createColumn( + const std::string &name, const std::string &arguments) { + // arguments contains a file name + if (arguments.empty()) { + throw std::runtime_error("invalid arguments for column '" + _name + + "': missing file name"); + } + if (arguments.find('/') != std::string::npos) { + throw std::runtime_error("invalid arguments for column '" + _name + + "': file name '" + arguments + + "' contains slash"); + } + return std::make_unique( + name, "Contents of logwatch file", _indirect_offset, _extra_offset, -1, + 0, _mc->mkLogwatchPath(), "/" + unescape_filename(arguments)); +} diff --git a/src/DynamicLogwatchFileColumn.h b/src/DynamicLogwatchFileColumn.h new file mode 100644 index 0000000..e071935 --- /dev/null +++ b/src/DynamicLogwatchFileColumn.h @@ -0,0 +1,53 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef DynamicLogwatchFileColumn_h +#define DynamicLogwatchFileColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "DynamicColumn.h" +class Column; +class Logger; +class MonitoringCore; + +class DynamicLogwatchFileColumn : public DynamicColumn { +public: + DynamicLogwatchFileColumn(const std::string &name, + const std::string &description, Logger *logger, + MonitoringCore *mc, int indirect_offset, + int extra_offset, int extra_extra_offset) + : DynamicColumn(name, description, logger, indirect_offset, + extra_offset, extra_extra_offset) + , _mc(mc) {} + ~DynamicLogwatchFileColumn() override = default; + std::unique_ptr createColumn(const std::string &name, + const std::string &arguments) override; + +private: + MonitoringCore *_mc; +}; + +#endif // DynamicLogwatchFileColumn_h diff --git a/src/EventConsoleConnection.cc b/src/EventConsoleConnection.cc new file mode 100644 index 0000000..4c039bf --- /dev/null +++ b/src/EventConsoleConnection.cc @@ -0,0 +1,89 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "EventConsoleConnection.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "Logger.h" + +EventConsoleConnection::EventConsoleConnection(Logger *logger, std::string path) + : _logger(logger), _path(std::move(path)) {} + +EventConsoleConnection::~EventConsoleConnection() { + Debug(_logger) << prefix("closing connection"); +} + +void EventConsoleConnection::run() { + boost::asio::local::stream_protocol::endpoint ep(_path); + // Attention, tricky timing-dependent stuff ahead: When we connect very + // rapidly, a no_buffer_space (= ENOBUFS) error can happen. This is probably + // caused by some internal Boost Kung Fu, remapping EGAIN to ENOBUFS, and + // looks like a bug in Boost, but that's a bit unclear. So instead of + // relying on Boost to retry under these circumstances, we do it ourselves. + boost::asio::local::stream_protocol::iostream stream; + while (true) { + stream.connect(ep); + if (stream.error() != + boost::system::error_code(boost::system::errc::no_buffer_space, + boost::system::system_category())) { + break; + } + Debug(_logger) << "retrying to connect"; + stream.clear(); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + check(stream, "connect"); + Debug(_logger) << prefix("successfully connected"); + + stream << std::nounitbuf; + sendRequest(stream); + stream.flush(); + stream.rdbuf()->shutdown(boost::asio::socket_base::shutdown_send); + check(stream, "send request"); + + receiveReply(stream); + check(stream, "receive reply"); +} + +std::string EventConsoleConnection::prefix(const std::string &message) const { + return "[mkeventd at " + _path + "] " + message; +} + +void EventConsoleConnection::check( + boost::asio::local::stream_protocol::iostream &stream, + const std::string &what) const { + if (!stream && !stream.eof()) { + // NOTE: Boost's system_error has a mutable string member for lazy + // construction of what(), this screws up cert-err60-cpp. :-P + throw boost::system::system_error(stream.error(), + prefix("cannot " + what)); // NOLINT + } +} diff --git a/src/EventConsoleConnection.h b/src/EventConsoleConnection.h new file mode 100644 index 0000000..f50727f --- /dev/null +++ b/src/EventConsoleConnection.h @@ -0,0 +1,52 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef EventConsoleConnection_h +#define EventConsoleConnection_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +class Logger; + +class EventConsoleConnection { +public: + EventConsoleConnection(Logger *logger, std::string path); + ~EventConsoleConnection(); + void run(); + +private: + virtual void sendRequest(std::ostream &os) = 0; + virtual void receiveReply(std::istream &is) = 0; + + [[nodiscard]] std::string prefix(const std::string &message) const; + void check(boost::asio::local::stream_protocol::iostream &stream, + const std::string &what) const; + + Logger *const _logger; + const std::string _path; +}; + +#endif // EventConsoleConnection_h diff --git a/src/FileSystem.h b/src/FileSystem.h new file mode 100644 index 0000000..079b7c5 --- /dev/null +++ b/src/FileSystem.h @@ -0,0 +1,34 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef FileSystem_h +#define FileSystem_h + +// IWYU pragma: begin_exports +#include +// IWYU pragma: end_exports + +namespace fs = std::experimental::filesystem; + +#endif // FileSystem_h diff --git a/src/Filter.cc b/src/Filter.cc new file mode 100644 index 0000000..e7c3c3b --- /dev/null +++ b/src/Filter.cc @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Filter.h" + +Filter::~Filter() = default; + +std::optional Filter::stringValueRestrictionFor( + const std::string& /* column_name */) const { + return {}; +} + +std::optional Filter::greatestLowerBoundFor( + const std::string& /* column_name */, + std::chrono::seconds /* timezone_offset */) const { + return {}; +} + +std::optional Filter::leastUpperBoundFor( + const std::string& /* column_name */, + std::chrono::seconds /* timezone_offset */) const { + return {}; +} + +std::optional> Filter::valueSetLeastUpperBoundFor( + const std::string& /* column_name */, + std::chrono::seconds /* timezone_offset */) const { + return {}; +} diff --git a/src/Filter.h b/src/Filter.h new file mode 100644 index 0000000..1e9b4bf --- /dev/null +++ b/src/Filter.h @@ -0,0 +1,102 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Filter_h +#define Filter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "contact_fwd.h" +class Column; +class Filter; +class Row; + +using Filters = std::vector>; + +/// A propositional formula over column value relations, kept in negation normal +/// form. +class Filter { +public: + enum Kind { row, stats, wait_condition }; + + explicit Filter(Kind kind) : _kind(kind) {} + virtual ~Filter(); + [[nodiscard]] Kind kind() const { return _kind; } + virtual bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const = 0; + virtual std::unique_ptr partialFilter( + std::function predicate) const = 0; + + // TODO(sp) We might be able to unify all the methods below if we make the + // underlying lattice structure explicit, i.e. provide a set type and + // corresponding meet/join operations. Perhaps we can even get rid of the + // std::optional by making the lattice bounded, i.e. by providing bottom/top + // values. + [[nodiscard]] virtual std::optional stringValueRestrictionFor( + const std::string &column_name) const; + [[nodiscard]] virtual std::optional greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const; + [[nodiscard]] virtual std::optional leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const; + [[nodiscard]] virtual std::optional> + valueSetLeastUpperBoundFor(const std::string &column_name, + std::chrono::seconds timezone_offset) const; + + [[nodiscard]] virtual std::unique_ptr copy() const = 0; + [[nodiscard]] virtual std::unique_ptr negate() const = 0; + + /// Checks for a *syntactic* tautology. + [[nodiscard]] virtual bool is_tautology() const = 0; + + /// Checks for a *syntactic* contradiction. + [[nodiscard]] virtual bool is_contradiction() const = 0; + + /// Combining the returned filters with *or* yields a filter equivalent to + /// the current one. + [[nodiscard]] virtual Filters disjuncts() const = 0; + + /// Combining the returned filters with *and* yields a filter equivalent to + /// the current one. + [[nodiscard]] virtual Filters conjuncts() const = 0; + + friend std::ostream &operator<<(std::ostream &os, const Filter &filter) { + return filter.print(os); + } + +private: + const Kind _kind; + virtual std::ostream &print(std::ostream &os) const = 0; +}; + +#endif // Filter_h diff --git a/src/FixedIntColumn.h b/src/FixedIntColumn.h new file mode 100644 index 0000000..32f6bc7 --- /dev/null +++ b/src/FixedIntColumn.h @@ -0,0 +1,46 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef FixedIntColumn_h +#define FixedIntColumn_h + +#include "config.h" // IWYU pragma: keep +#include "IntColumn.h" + +class FixedIntColumn : public IntColumn { +public: + FixedIntColumn(const std::string& name, const std::string& description, + int value) + : IntColumn(name, description, -1, -1, -1, 0), _value(value) {} + + int32_t getValue(Row /* row */, + const contact* /* auth_user */) const override { + return _value; + } + +private: + const int32_t _value; +}; + +#endif // FixedIntColumn_h diff --git a/src/HostContactsColumn.cc b/src/HostContactsColumn.cc new file mode 100644 index 0000000..e57695d --- /dev/null +++ b/src/HostContactsColumn.cc @@ -0,0 +1,60 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostContactsColumn.h" +#include "Row.h" + +#ifdef CMC +#include "ContactList.h" +#include "Object.h" +#include "cmc.h" +#else +#include +#include "nagios.h" +#endif + +std::vector HostContactsColumn::getValue( + Row row, const contact* /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { +#ifdef CMC + if (auto object = columnData(row)) { + return object->_contact_list->contactNames(); + } + return {}; +#else + std::unordered_set names; + if (auto hst = columnData(row)) { + for (auto cm = hst->contacts; cm != nullptr; cm = cm->next) { + names.insert(cm->contact_ptr->name); + } + for (auto cgm = hst->contact_groups; cgm != nullptr; cgm = cgm->next) { + for (auto cm = cgm->group_ptr->members; cm != nullptr; + cm = cm->next) { + names.insert(cm->contact_ptr->name); + } + } + } + return std::vector(names.begin(), names.end()); +#endif +} diff --git a/src/HostContactsColumn.h b/src/HostContactsColumn.h new file mode 100644 index 0000000..0455cc7 --- /dev/null +++ b/src/HostContactsColumn.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostContactsColumn_h +#define HostContactsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class Row; + +class HostContactsColumn : public ListColumn { +public: + HostContactsColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + std::vector getValue( + Row row, const contact* auth_user, + std::chrono::seconds timezone_offset) const override; +}; + +#endif // HostContactsColumn_h diff --git a/src/HostFileColumn.cc b/src/HostFileColumn.cc new file mode 100644 index 0000000..c201343 --- /dev/null +++ b/src/HostFileColumn.cc @@ -0,0 +1,117 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostFileColumn.h" +#include +#include +#include +#include +#include +#include +#include +#include "Logger.h" +#include "Row.h" + +#ifdef CMC +#include "Host.h" +#else +#include "nagios.h" +#endif + +HostFileColumn::HostFileColumn(const std::string& name, + const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, + std::string base_dir, std::string suffix) + : BlobColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _base_dir(std::move(base_dir)) + , _suffix(std::move(suffix)) {} + +std::unique_ptr> HostFileColumn::getValue(Row row) const { + if (_base_dir.empty()) { + return nullptr; // Path is not configured + } + +#ifdef CMC + auto hst = columnData(row); + if (hst == nullptr) { + return nullptr; + } + std::string host_name = hst->name(); +#else + auto hst = columnData(row); + if (hst == nullptr) { + return nullptr; + } + std::string host_name = hst->name; +#endif + + std::string path = _base_dir + "/" + host_name + _suffix; + int fd = open(path.c_str(), O_RDONLY); + if (fd == -1) { + // It is OK when inventory/logwatch files do not exist. + if (errno != ENOENT) { + generic_error ge("cannot open " + path); + Warning(logger()) << ge; + } + return nullptr; + } + + struct stat st; + if (fstat(fd, &st) == -1) { + generic_error ge("cannot stat " + path); + Warning(logger()) << ge; + return nullptr; + } + if (!S_ISREG(st.st_mode)) { + Warning(logger()) << path << " is not a regular file"; + return nullptr; + } + + size_t bytes_to_read = st.st_size; + auto result = std::make_unique>(bytes_to_read); + char* buffer = &(*result)[0]; + while (bytes_to_read > 0) { + ssize_t bytes_read = read(fd, buffer, bytes_to_read); + if (bytes_read == -1) { + if (errno != EINTR) { + generic_error ge("could not read " + path); + Warning(logger()) << ge; + close(fd); + return nullptr; + } + } else if (bytes_read == 0) { + Warning(logger()) << "premature EOF reading " << path; + close(fd); + return nullptr; + } else { + bytes_to_read -= bytes_read; + buffer += bytes_read; + } + } + + close(fd); + return result; +} diff --git a/src/HostFileColumn.h b/src/HostFileColumn.h new file mode 100644 index 0000000..c355474 --- /dev/null +++ b/src/HostFileColumn.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostFileColumn_h +#define HostFileColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "BlobColumn.h" +class Row; + +class HostFileColumn : public BlobColumn { +public: + HostFileColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, std::string base_dir, + std::string suffix); + + [[nodiscard]] std::unique_ptr> getValue( + Row row) const override; + +private: + std::string _base_dir; + std::string _suffix; +}; + +#endif // HostFileColumn_h diff --git a/src/HostGroupsColumn.cc b/src/HostGroupsColumn.cc new file mode 100644 index 0000000..63460aa --- /dev/null +++ b/src/HostGroupsColumn.cc @@ -0,0 +1,60 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostGroupsColumn.h" +#include "Row.h" + +#ifdef CMC +#include "Object.h" +#include "ObjectGroup.h" +#include "cmc.h" +#else +#include "auth.h" +#include "nagios.h" +#endif + +std::vector HostGroupsColumn::getValue( + Row row, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + std::vector group_names; +#ifdef CMC + if (auto object = columnData(row)) { + for (const auto &og : object->_groups) { + if (og->isContactAuthorized(_mc, auth_user)) { + group_names.push_back(og->name()); + } + } + } +#else + if (auto p = columnData(row)) { + for (objectlist *list = *p; list != nullptr; list = list->next) { + auto hg = static_cast(list->object_ptr); + if (is_authorized_for_host_group(_mc, hg, auth_user)) { + group_names.emplace_back(hg->group_name); + } + } + } +#endif + return group_names; +} diff --git a/src/HostGroupsColumn.h b/src/HostGroupsColumn.h new file mode 100644 index 0000000..b74023f --- /dev/null +++ b/src/HostGroupsColumn.h @@ -0,0 +1,54 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostGroupsColumn_h +#define HostGroupsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class MonitoringCore; +class Row; + +class HostGroupsColumn : public ListColumn { +public: + HostGroupsColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, MonitoringCore *mc) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) {} + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *const _mc; +}; + +#endif // HostGroupsColumn_h diff --git a/src/HostListColumn.cc b/src/HostListColumn.cc new file mode 100644 index 0000000..5e1ce5b --- /dev/null +++ b/src/HostListColumn.cc @@ -0,0 +1,96 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostListColumn.h" +#include +#include +#include "Renderer.h" +#include "Row.h" + +#ifdef CMC +#include +#include "Host.h" +#include "LogEntry.h" +#include "State.h" +#include "cmc.h" +#else +#include "auth.h" +#include "nagios.h" +#endif + +void HostListColumn::output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + ListRenderer l(r); + for (const auto &member : getMembers(row, auth_user)) { + if (_show_state) { + SublistRenderer s(l); + s.output(member.host_name); + s.output(static_cast(member.current_state)); + s.output(static_cast(member.has_been_checked)); + } else { + l.output(member.host_name); + } + } +} + +std::vector HostListColumn::getValue( + Row row, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + auto members = getMembers(row, auth_user); + std::vector host_names; + std::transform(members.begin(), members.end(), + std::back_inserter(host_names), + [](const auto &member) { return member.host_name; }); + return host_names; +}; + +std::vector HostListColumn::getMembers( + Row row, const contact *auth_user) const { + std::vector members; +#ifdef CMC + if (auto p = columnData>(row)) { + for (const auto &hst : *p) { + if (auth_user == nullptr || hst->hasContact(_mc, auth_user)) { + members.emplace_back( + hst->name(), + static_cast(hst->state()->_current_state), + hst->state()->_has_been_checked); + } + } + } +#else + if (auto p = columnData(row)) { + for (const hostsmember *mem = *p; mem != nullptr; mem = mem->next) { + host *hst = mem->host_ptr; + if (auth_user == nullptr || + is_authorized_for(_mc, auth_user, hst, nullptr)) { + members.emplace_back(hst->name, + static_cast(hst->current_state), + hst->has_been_checked != 0); + } + } + } +#endif + return members; +} diff --git a/src/HostListColumn.h b/src/HostListColumn.h new file mode 100644 index 0000000..b7a86da --- /dev/null +++ b/src/HostListColumn.h @@ -0,0 +1,76 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostListColumn_h +#define HostListColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +enum class HostState; +class MonitoringCore; +class Row; +class RowRenderer; + +class HostListColumn : public ListColumn { +public: + HostListColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, MonitoringCore *mc, + bool show_state) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _show_state(show_state) {} + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const override; + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *_mc; + const bool _show_state; + + struct Member { + Member(std::string hn, HostState cs, bool hbc) + : host_name(std::move(hn)) + , current_state(cs) + , has_been_checked(hbc) {} + + std::string host_name; + HostState current_state; + bool has_been_checked; + }; + + std::vector getMembers(Row row, const contact *auth_user) const; +}; + +#endif // HostListColumn_h diff --git a/src/HostListStateColumn.cc b/src/HostListStateColumn.cc new file mode 100644 index 0000000..a8a95ba --- /dev/null +++ b/src/HostListStateColumn.cc @@ -0,0 +1,129 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostListStateColumn.h" +#include "LogEntry.h" +#include "Row.h" + +#ifdef CMC +#include +#include "Host.h" +#include "State.h" +#else +#include "auth.h" +#endif + +int32_t HostListStateColumn::getValue(Row row, const contact *auth_user) const { + int32_t result = 0; +#ifdef CMC + if (auto p = columnData>(row)) { + for (auto hst : *p) { + if (auth_user == nullptr || hst->hasContact(_mc, auth_user)) { + update(hst, auth_user, result); + } + } + } +#else + if (auto p = columnData(row)) { + for (hostsmember *mem = *p; mem != nullptr; mem = mem->next) { + host *hst = mem->host_ptr; + if (auth_user == nullptr || + is_authorized_for(_mc, auth_user, hst, nullptr)) { + update(hst, auth_user, result); + } + } + } +#endif + return result; +} + +void HostListStateColumn::update(host *hst, const contact *auth_user, + int32_t &result) const { +#ifdef CMC + ServiceListStateColumn::service_list services = &hst->_services; + bool has_been_checked = hst->state()->_has_been_checked; + auto current_state = static_cast(hst->state()->_current_state); +#else + ServiceListStateColumn::service_list services = hst->services; + bool has_been_checked = hst->has_been_checked != 0; + int current_state = hst->current_state; +#endif + switch (_logictype) { + case Type::num_svc_pending: + case Type::num_svc_ok: + case Type::num_svc_warn: + case Type::num_svc_crit: + case Type::num_svc_unknown: + case Type::num_svc: + result += ServiceListStateColumn::getValueFromServices( + _mc, static_cast(_logictype), + services, auth_user); + break; + + case Type::worst_svc_state: { + int state = ServiceListStateColumn::getValueFromServices( + _mc, static_cast(_logictype), + services, auth_user); + if (worse(static_cast(state), + static_cast(result))) { + result = state; + } + break; + } + + case Type::num_hst_up: + case Type::num_hst_down: + case Type::num_hst_unreach: + if (has_been_checked && + current_state == static_cast(_logictype) - + static_cast(Type::num_hst_up)) { + result++; + } + break; + + case Type::num_hst_pending: + if (!has_been_checked) { + result++; + } + break; + + case Type::num_hst: + result++; + break; + + case Type::worst_hst_state: + if (worse(static_cast(current_state), + static_cast(result))) { + result = current_state; + } + break; + case Type::num_svc_hard_ok: + case Type::num_svc_hard_warn: + case Type::num_svc_hard_crit: + case Type::num_svc_hard_unknown: + case Type::worst_svc_hard_state: + // TODO(sp) Why are these not handled? + break; + } +} diff --git a/src/HostListStateColumn.h b/src/HostListStateColumn.h new file mode 100644 index 0000000..187c094 --- /dev/null +++ b/src/HostListStateColumn.h @@ -0,0 +1,92 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostListStateColumn_h +#define HostListStateColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +#include "ServiceListStateColumn.h" +class MonitoringCore; +class Row; + +#ifdef CMC +#include "cmc.h" +#else +#include "nagios.h" +#endif + +class HostListStateColumn : public IntColumn { +public: + // TODO(sp) Remove the magic arithmetic + enum class Type { + num_svc = static_cast(ServiceListStateColumn::Type::num), + num_svc_pending = + static_cast(ServiceListStateColumn::Type::num_pending), + num_svc_ok = static_cast(ServiceListStateColumn::Type::num_ok), + num_svc_warn = static_cast(ServiceListStateColumn::Type::num_warn), + num_svc_crit = static_cast(ServiceListStateColumn::Type::num_crit), + num_svc_unknown = + static_cast(ServiceListStateColumn::Type::num_unknown), + worst_svc_state = + static_cast(ServiceListStateColumn::Type::worst_state), + num_svc_hard_ok = + static_cast(ServiceListStateColumn::Type::num_hard_ok), + num_svc_hard_warn = + static_cast(ServiceListStateColumn::Type::num_hard_warn), + num_svc_hard_crit = + static_cast(ServiceListStateColumn::Type::num_hard_crit), + num_svc_hard_unknown = + static_cast(ServiceListStateColumn::Type::num_hard_unknown), + worst_svc_hard_state = + static_cast(ServiceListStateColumn::Type::worst_hard_state), + num_hst_up = 10, + num_hst_down = 11, + num_hst_unreach = 12, + num_hst_pending = 13, + num_hst = -11, + worst_hst_state = -12, + }; + + HostListStateColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, MonitoringCore *mc, + Type logictype) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _logictype(logictype) {} + + int32_t getValue(Row row, const contact *auth_user) const override; + +private: + MonitoringCore *_mc; + const Type _logictype; + + void update(host *hst, const contact *auth_user, int32_t &result) const; +}; + +#endif // HostListStateColumn_h diff --git a/src/HostServiceState.cc b/src/HostServiceState.cc new file mode 100644 index 0000000..33f0189 --- /dev/null +++ b/src/HostServiceState.cc @@ -0,0 +1,94 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostServiceState.h" + +HostServiceState::HostServiceState() + : _is_host(false) + , _time(0) + , _lineno(0) + , _from(0) + , _until(0) + , _duration(0) + , _duration_part(0) + , _duration_state_UNMONITORED(0) + , _duration_part_UNMONITORED(0) + , _duration_state_OK(0) + , _duration_part_OK(0) + , _duration_state_WARNING(0) + , _duration_part_WARNING(0) + , _duration_state_CRITICAL(0) + , _duration_part_CRITICAL(0) + , _duration_state_UNKNOWN(0) + , _duration_part_UNKNOWN(0) + , _host_down(0) + , _state(0) + , _in_notification_period(0) + , _in_service_period(0) + , _in_downtime(0) + , _in_host_downtime(0) + , _is_flapping(0) + , _may_no_longer_exist(false) + , _has_vanished(false) + , _last_known_time(0) + , _host(nullptr) + , _service(nullptr) {} + +#ifdef CMC +void HostServiceState::computePerStateDurations() { + _duration_state_UNMONITORED = 0; + _duration_part_UNMONITORED = 0; + _duration_state_OK = 0; + _duration_part_OK = 0; + _duration_state_WARNING = 0; + _duration_part_WARNING = 0; + _duration_state_CRITICAL = 0; + _duration_part_CRITICAL = 0; + _duration_state_UNKNOWN = 0; + _duration_part_UNKNOWN = 0; + + switch (_state) { + case -1: + _duration_state_UNMONITORED = _duration; + _duration_part_UNMONITORED = _duration_part; + break; + case 0: + _duration_state_OK = _duration; + _duration_part_OK = _duration_part; + break; + case 1: + _duration_state_WARNING = _duration; + _duration_part_WARNING = _duration_part; + break; + case 2: + _duration_state_CRITICAL = _duration; + _duration_part_CRITICAL = _duration_part; + break; + case 3: + _duration_state_UNKNOWN = _duration; + _duration_part_UNKNOWN = _duration_part; + break; + } +} +#endif diff --git a/src/HostServiceState.h b/src/HostServiceState.h new file mode 100644 index 0000000..88a8b2c --- /dev/null +++ b/src/HostServiceState.h @@ -0,0 +1,107 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostServiceState_h +#define HostServiceState_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +class HostServiceState; + +// for host/service, ugly... +#ifdef CMC +#include "cmc.h" +#else +#include "nagios.h" +#endif + +using HostServices = std::vector; + +using HostServiceKey = void *; + +class HostServiceState { +public: + bool _is_host; + time_t _time; + int32_t _lineno; + time_t _from; + time_t _until; + + time_t _duration; + double _duration_part; + + time_t _duration_state_UNMONITORED; + double _duration_part_UNMONITORED; + + time_t _duration_state_OK; + double _duration_part_OK; + + time_t _duration_state_WARNING; + double _duration_part_WARNING; + + time_t _duration_state_CRITICAL; + double _duration_part_CRITICAL; + + time_t _duration_state_UNKNOWN; + double _duration_part_UNKNOWN; + + // State information + int _host_down; // used if service + int _state; // -1/0/1/2/3 + int _in_notification_period; + int _in_service_period; + int _in_downtime; + int _in_host_downtime; + int _is_flapping; + + // Service information + HostServices _services; + + // Absent state handling + bool _may_no_longer_exist; + bool _has_vanished; + time_t _last_known_time; + + std::string _debug_info; + std::string _log_output; + + // maybe "": -> no period known, we assume "always" + std::string _notification_period; + // maybe "": -> no period known, we assume "always" + std::string _service_period; + host *_host; + service *_service; + std::string _host_name; // Fallback if host no longer exists + std::string _service_description; // Fallback if service no longer exists + + HostServiceState(); +#ifdef CMC + void computePerStateDurations(); +#endif +}; + +#endif // HostServiceState_h diff --git a/src/HostSpecialDoubleColumn.cc b/src/HostSpecialDoubleColumn.cc new file mode 100644 index 0000000..d8c4d1f --- /dev/null +++ b/src/HostSpecialDoubleColumn.cc @@ -0,0 +1,133 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostSpecialDoubleColumn.h" +#include "Row.h" + +#ifdef CMC +#include +#include "Object.h" +#include "State.h" +#include "Timeperiod.h" +#else +#include +#include "nagios.h" +#endif + +double HostSpecialDoubleColumn::getValue(Row row) const { +#ifdef CMC + if (auto object = columnData(row)) { + switch (_type) { + case Type::staleness: + return staleness(object); + } + } +#else + if (auto hst = columnData(row)) { + switch (_type) { + case Type::staleness: { + extern int interval_length; + return static_cast(time(nullptr) - hst->last_check) / + ((hst->check_interval == 0 ? 1 : hst->check_interval) * + interval_length); + } + } + } +#endif + return 0; +} + +#ifdef CMC +// static +double HostSpecialDoubleColumn::staleness(const Object *object) { + auto state = object->state(); + std::chrono::system_clock::duration check_result_age; + const Timeperiod *check_period = object->_check_period; + std::chrono::system_clock::time_point last_period_change = + check_period->lastStateChange(); + std::chrono::system_clock::time_point last_check = state->_last_check; + + // Compute the age of the check result. When the check is currently in its + // check period then... + auto m_now = std::chrono::system_clock::now(); + if (check_period->isActive()) { + // Has a check happened since the beginning of the current phase? Then + // simply compare last check with current time. This should be the 99% + // case. + if (last_check >= last_period_change) { + check_result_age = m_now - last_check; + + } else { + // otherwise the active phase has just begun. Take the time since + // the beginning of the phase. + check_result_age = m_now - last_period_change; + + // Add time at the end of the pre-last transition + std::chrono::system_clock::time_point prelast_period_change = + check_period->previousLastStateChange(); + if (prelast_period_change != + std::chrono::system_clock::time_point()) { + if (last_check < prelast_period_change) { + check_result_age += prelast_period_change - last_check; + } + // else: a check happend out of the check period. Ignore this + } + // else: no information about past. Ignore this + } + } else { + // Check is currently out of its check period? Then use the beginning of + // the inactive phase as reference for computing the check age. This + // effectively freezes the staleness value when a goes goes into its + // inactive phase. + if (last_period_change != std::chrono::system_clock::time_point()) { + check_result_age = last_period_change - last_check; + } else { + // e.g. for timeperiod "never" + check_result_age = std::chrono::seconds(0); + } + } + + // Is the checks' result based on cached agent data? Then use the age of + // that data as check result age + std::chrono::duration interval; + if (state->_cached_at != std::chrono::system_clock::time_point()) { + // Cache interval and check interval can add up in the worst case. + interval = state->_cache_interval + object->_check_interval; + + std::chrono::system_clock::duration cached_age = + m_now - state->_cached_at; + if (cached_age > check_result_age) { + check_result_age = cached_age; + } + } else { + interval = object->_check_interval; + } + + // Check_MK configures the interval for its passive checks correctly. Just + // make sure that we do not fail if it is set to 0 by some error. + return std::chrono::duration_cast(check_result_age) + .count() / + (interval == std::chrono::seconds(0) ? 1 : interval.count()); +} +#endif diff --git a/src/HostSpecialDoubleColumn.h b/src/HostSpecialDoubleColumn.h new file mode 100644 index 0000000..59840df --- /dev/null +++ b/src/HostSpecialDoubleColumn.h @@ -0,0 +1,59 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostSpecialDoubleColumn_h +#define HostSpecialDoubleColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "DoubleColumn.h" +class Row; + +#ifdef CMC +class Object; +#endif + +class HostSpecialDoubleColumn : public DoubleColumn { +public: + enum class Type { staleness }; + + HostSpecialDoubleColumn(const std::string& name, + const std::string& description, int indirect, + int extra_offset, int extra_extra_offset, + int offset, Type hsdc_type) + : DoubleColumn(name, description, indirect, extra_offset, + extra_extra_offset, offset) + , _type(hsdc_type) {} + + [[nodiscard]] double getValue(Row row) const override; + +#ifdef CMC + static double staleness(const Object* object); +#endif + +private: + const Type _type; +}; + +#endif // HostSpecialDoubleColumn_h diff --git a/src/HostSpecialIntColumn.cc b/src/HostSpecialIntColumn.cc new file mode 100644 index 0000000..b23321b --- /dev/null +++ b/src/HostSpecialIntColumn.cc @@ -0,0 +1,92 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "HostSpecialIntColumn.h" +#include "MonitoringCore.h" +#include "Row.h" +#include "mk_inventory.h" + +#ifdef CMC +#include "Core.h" +#include "Host.h" +#include "Object.h" +#include "RRDBackend.h" +#include "RRDInfoCache.h" +#include "State.h" +#include "cmc.h" +#else +#include "nagios.h" +#include "pnp4nagios.h" +#endif + +int32_t HostSpecialIntColumn::getValue(Row row, + const contact* /* auth_user */) const { +#ifdef CMC + if (auto object = columnData(row)) { + switch (_type) { + case Type::real_hard_state: { + if (object->isCurrentStateOK()) { + return 0; + } + auto state = object->state(); + return state->_state_type == StateType::hard + ? state->_current_state + : state->_last_hard_state; + } + case Type::pnp_graph_present: + return _mc->impl() + ->_rrd_backend.infoFor(object) + ._names.empty() + ? 0 + : 1; + case Type::mk_inventory_last: + return static_cast(mk_inventory_last( + _mc->mkInventoryPath() + "/" + object->host()->name())); + } + } +#else + if (auto hst = columnData(row)) { + switch (_type) { + case Type::real_hard_state: + if (hst->current_state == 0) { + return 0; + } + if (hst->state_type == HARD_STATE) { + return hst->current_state; + } + return hst->last_hard_state; + + case Type::pnp_graph_present: + return pnpgraph_present(_mc, hst->name, + dummy_service_description()); + + case Type::mk_inventory_last: { + return static_cast(mk_inventory_last( + _mc->mkInventoryPath() + "/" + hst->name)); + } + } + } +#endif + return 0; +} diff --git a/src/HostSpecialIntColumn.h b/src/HostSpecialIntColumn.h new file mode 100644 index 0000000..f9f4b1d --- /dev/null +++ b/src/HostSpecialIntColumn.h @@ -0,0 +1,56 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef HostSpecialIntColumn_h +#define HostSpecialIntColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +#include "contact_fwd.h" +class MonitoringCore; +class Row; + +class HostSpecialIntColumn : public IntColumn { +public: + enum class Type { real_hard_state, pnp_graph_present, mk_inventory_last }; + + HostSpecialIntColumn(const std::string &name, + const std::string &description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset, + MonitoringCore *mc, Type hsic_type) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _type(hsic_type) {} + + int32_t getValue(Row row, const contact *auth_user) const override; + +private: + MonitoringCore *_mc; + const Type _type; +}; + +#endif // HostSpecialIntColumn_h diff --git a/src/InputBuffer.cc b/src/InputBuffer.cc new file mode 100644 index 0000000..42f9e14 --- /dev/null +++ b/src/InputBuffer.cc @@ -0,0 +1,252 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "InputBuffer.h" +#include +#include +#include +#include +#include +#include "Logger.h" +#include "Poller.h" + +namespace { +const size_t initial_buffer_size = 4096; +// TODO(sp): Make this configurable? +const size_t maximum_buffer_size = 500 * 1024 * 1024; + +bool timeout_reached(const std::chrono::system_clock::time_point &start, + const std::chrono::milliseconds &timeout) { + return (timeout != std::chrono::milliseconds(0)) && + (std::chrono::system_clock::now() - start >= timeout); +} +} // namespace + +std::ostream &operator<<(std::ostream &os, const InputBuffer::Result &r) { + switch (r) { + case InputBuffer::Result::request_read: + return os << "request read"; + case InputBuffer::Result::data_read: + return os << "data read"; + case InputBuffer::Result::unexpected_eof: + return os << "unexpected EOF"; + case InputBuffer::Result::should_terminate: + return os << "should terminate"; + case InputBuffer::Result::line_too_long: + return os << "line too long"; + case InputBuffer::Result::eof: + return os << "EOF"; + case InputBuffer::Result::empty_request: + return os << "empty request"; + case InputBuffer::Result::timeout: + return os << "timeout"; + } + return os; // never reached +} + +InputBuffer::InputBuffer(int fd, const bool &termination_flag, Logger *logger, + std::chrono::milliseconds query_timeout, + std::chrono::milliseconds idle_timeout) + : _fd(fd) + , _termination_flag(termination_flag) + , _query_timeout(query_timeout) + , _idle_timeout(idle_timeout) + , _readahead_buffer(initial_buffer_size) + , _logger(logger) { + _read_index = 0; // points to data not yet processed + _write_index = 0; // points to end of data in buffer +} + +// read in data enough for one complete request (and maybe more). +InputBuffer::Result InputBuffer::readRequest() { + // Remember when we started waiting for a request. This is needed for the + // idle_timeout. A connection may not be idle longer than that value. + auto start_of_idle = std::chrono::system_clock::now(); + + // Remember if we have read some part of the query. During + // a query the timeout is another (short) than between + // queries. + bool query_started = false; + + // _read_index points to the place in the buffer, where the + // next valid data begins. This data ends at _write_index. + // That data might have been read while reading the previous + // request. + + // r is used to find the end of the line + size_t r = _read_index; + + while (true) { + // Try to find end of the current line in buffer + while (r < _write_index && _readahead_buffer[r] != '\n') { + r++; // now r is at end of data or at '\n' + } + + // If we cannot find the end of line in the data + // already read, then we need to read new data from + // the client. + if (r == _write_index) { + // Is there still space left in the buffer => read in + // further data into the buffer. + if (_write_index < _readahead_buffer.capacity()) { + Result rd = + readData(); // tries to read in further data into buffer + if (rd == Result::timeout) { + if (query_started) { + Informational(_logger) + << "Timeout of " << _query_timeout.count() + << " ms exceeded while reading query"; + return Result::timeout; + } + // Check if we exceeded the maximum time between two queries + if (timeout_reached(start_of_idle, _idle_timeout)) { + Informational(_logger) + << "Idle timeout of " << _idle_timeout.count() + << " ms exceeded. Going to close connection."; + return Result::timeout; + } + } + + // Are we at end of file? That is only an error, if we've + // read an incomplete line. If the last thing we read was + // a linefeed, then we consider the current request to + // be valid, if it is not empty. + else if ( + rd == Result::eof && + r == _read_index /* currently at beginning of a line */) { + if (_request_lines.empty()) { + return Result::eof; // empty request -> no request + } + // socket has been closed but request is complete + return Result::request_read; + // the current state is now: + // _read_index == r == _write_index => buffer is empty + // that way, if the main program tries to read the + // next request, it will get an IB_UNEXPECTED_EOF + + } + // if we are *not* at an end of line while reading + // a request, we got an invalid request. + else if (rd == Result::eof) { + return Result::unexpected_eof; + + // Other status codes + } else if (rd == Result::should_terminate) { + return rd; + } + } + // OK. So no space is left in the buffer. But maybe at the + // *beginning* of the buffer is space left again. This is + // very probable if _write_index == _readahead_buffer.capacity(). + // Most + // of the buffer's content is already processed. So we simply + // shift the yet unprocessed data to the very left of the buffer. + else if (_read_index > 0) { + size_t shift_by = + _read_index; // distance to beginning of buffer + size_t size = + _write_index - _read_index; // amount of data to shift + memmove(&_readahead_buffer[0], &_readahead_buffer[_read_index], + size); + _read_index = 0; // unread data is now at the beginning + _write_index -= shift_by; // write pointer shifted to the left + r -= shift_by; // current scan position also shift left + // continue -> still no data in buffer, but it will + // be read, as now is space + } + // buffer is full, but still no end of line found + else { + size_t new_capacity = _readahead_buffer.capacity() * 2; + if (new_capacity > maximum_buffer_size) { + Informational(_logger) + << "Error: maximum length of request line exceeded"; + return Result::line_too_long; + } + _readahead_buffer.resize(new_capacity); + } + } else // end of line found + { + if (_read_index == r) { // empty line found => end of request + _read_index = r + 1; + // Was ist, wenn noch keine korrekte Zeile gelesen wurde? + if (_request_lines.empty()) { + return Result::empty_request; + } + return Result::request_read; + + } // non-empty line: belongs to current request + size_t length = r - _read_index; + for (size_t end = r; end > _read_index && + (isspace(_readahead_buffer[--end]) != 0);) { + length--; + } + if (length > 0) { + _request_lines.emplace_back(&_readahead_buffer[_read_index], + length); + } else { + Informational(_logger) + << "Warning ignoring line containing only whitespace"; + } + query_started = true; + _read_index = r + 1; + r = _read_index; + } + } +} + +// read at least *some* data. Return IB_TIMEOUT if that lasts more than +// _query_timeout msecs. +InputBuffer::Result InputBuffer::readData() { + auto start = std::chrono::system_clock::now(); + while (!_termination_flag) { + if (timeout_reached(start, _query_timeout)) { + return Result::timeout; + } + + Poller poller; + poller.addFileDescriptor(_fd, PollEvents::in); + int retval = poller.poll(std::chrono::milliseconds(200)); + if (retval > 0 && poller.isFileDescriptorSet(_fd, PollEvents::in)) { + ssize_t r = read(_fd, &_readahead_buffer[_write_index], + _readahead_buffer.capacity() - _write_index); + if (r < 0) { + return Result::eof; + } + if (r == 0) { + return Result::eof; + } + _write_index += r; + return Result::data_read; + } + } + return Result::should_terminate; +} + +bool InputBuffer::empty() const { return _request_lines.empty(); } + +std::string InputBuffer::nextLine() { + std::string s = _request_lines.front(); + _request_lines.pop_front(); + return s; +} diff --git a/src/InputBuffer.h b/src/InputBuffer.h new file mode 100644 index 0000000..ee35ac8 --- /dev/null +++ b/src/InputBuffer.h @@ -0,0 +1,73 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef InputBuffer_h +#define InputBuffer_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +class Logger; + +class InputBuffer { +public: + enum class Result { + request_read, + data_read, + unexpected_eof, + should_terminate, + line_too_long, + eof, + empty_request, + timeout + }; + + friend std::ostream &operator<<(std::ostream &os, const Result &r); + + InputBuffer(int fd, const bool &termination_flag, Logger *logger, + std::chrono::milliseconds query_timeout, + std::chrono::milliseconds idle_timeout); + Result readRequest(); + [[nodiscard]] bool empty() const; + std::string nextLine(); + +private: + int _fd; + const bool &_termination_flag; + std::chrono::milliseconds _query_timeout; + std::chrono::milliseconds _idle_timeout; + std::vector _readahead_buffer; + size_t _read_index; + size_t _write_index; + std::list _request_lines; + Logger *const _logger; + + Result readData(); +}; + +#endif // InputBuffer_h diff --git a/src/IntAggregator.h b/src/IntAggregator.h new file mode 100644 index 0000000..d162f28 --- /dev/null +++ b/src/IntAggregator.h @@ -0,0 +1,55 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef IntAggregator_h +#define IntAggregator_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Aggregator.h" +#include "IntColumn.h" +#include "contact_fwd.h" +class Row; +class RowRenderer; + +class IntAggregator : public Aggregator { +public: + IntAggregator(const AggregationFactory &factory, const IntColumn *column) + : _aggregation(factory()), _column(column) {} + + void consume(Row row, const contact *auth_user, + std::chrono::seconds /* timezone_offset*/) override { + _aggregation->update(_column->getValue(row, auth_user)); + } + + void output(RowRenderer &r) const override { + r.output(_aggregation->value()); + } + +private: + std::unique_ptr _aggregation; + const IntColumn *const _column; +}; + +#endif // IntAggregator_h diff --git a/src/IntColumn.cc b/src/IntColumn.cc new file mode 100644 index 0000000..14836e4 --- /dev/null +++ b/src/IntColumn.cc @@ -0,0 +1,47 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "IntColumn.h" +#include "Aggregator.h" +#include "Filter.h" +#include "IntAggregator.h" +#include "IntFilter.h" +#include "Renderer.h" +#include "Row.h" + +void IntColumn::output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + r.output(getValue(row, auth_user)); +} + +std::unique_ptr IntColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, value); +} + +std::unique_ptr IntColumn::createAggregator( + AggregationFactory factory) const { + return std::make_unique(factory, this); +} diff --git a/src/IntColumn.h b/src/IntColumn.h new file mode 100644 index 0000000..07374da --- /dev/null +++ b/src/IntColumn.h @@ -0,0 +1,64 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef IntColumn_h +#define IntColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class IntColumn : public Column { +public: + IntColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset) + : Column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] ColumnType type() const override { return ColumnType::int_; } + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; + + virtual int32_t getValue(Row row, const contact *auth_user) const = 0; +}; + +#endif // IntColumn_h diff --git a/src/IntFilter.cc b/src/IntFilter.cc new file mode 100644 index 0000000..fce79a4 --- /dev/null +++ b/src/IntFilter.cc @@ -0,0 +1,149 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "IntFilter.h" +#include +#include "Filter.h" +#include "IntColumn.h" +#include "Row.h" + +IntFilter::IntFilter(Kind kind, const IntColumn &column, + RelationalOperator relOp, const std::string &value) + : ColumnFilter(kind, column, relOp, value) + , _column(column) + , _ref_value(atoi(value.c_str())) {} + +namespace { +bool eval(int32_t x, RelationalOperator op, int32_t y) { + switch (op) { + case RelationalOperator::equal: + return x == y; + case RelationalOperator::not_equal: + return x != y; + case RelationalOperator::matches: // superset + return (x & y) == y; + case RelationalOperator::doesnt_match: // not superset + return (x & y) != y; + case RelationalOperator::equal_icase: // subset + return (x & y) == x; + case RelationalOperator::not_equal_icase: // not subset + return (x & y) != x; + case RelationalOperator::matches_icase: // contains any + return (x & y) != 0; + case RelationalOperator::doesnt_match_icase: // contains none of + return (x & y) == 0; + case RelationalOperator::less: + return x < y; + case RelationalOperator::greater_or_equal: + return x >= y; + case RelationalOperator::greater: + return x > y; + case RelationalOperator::less_or_equal: + return x <= y; + } + return false; +} +} // namespace + +bool IntFilter::accepts(Row row, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + return eval(_column.getValue(row, auth_user), oper(), _ref_value); +} + +std::optional IntFilter::greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds /* timezone_offset */) const { + if (column_name != columnName()) { + return {}; // wrong column + } + switch (oper()) { + case RelationalOperator::equal: + case RelationalOperator::greater_or_equal: + return {_ref_value}; + case RelationalOperator::greater: + return {_ref_value + 1}; + case RelationalOperator::not_equal: + case RelationalOperator::matches: // superset + case RelationalOperator::doesnt_match: // not superset + case RelationalOperator::equal_icase: // subset + case RelationalOperator::not_equal_icase: // not subset + case RelationalOperator::matches_icase: // contains any + case RelationalOperator::doesnt_match_icase: // contains none of + case RelationalOperator::less: + case RelationalOperator::less_or_equal: + // NOTE: If we use the equivalent 'return {}' here and the other + // std::nullopt occurences below, we run into g++/libstdc++ bug + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86465. :-/ + return std::nullopt; + } + return std::nullopt; // unreachable +} + +std::optional IntFilter::leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds /* timezone_offset */) const { + if (column_name != columnName()) { + return {}; // wrong column + } + switch (oper()) { + case RelationalOperator::equal: + case RelationalOperator::less_or_equal: + return {_ref_value}; + case RelationalOperator::less: + return {_ref_value - 1}; + case RelationalOperator::not_equal: + case RelationalOperator::matches: // superset + case RelationalOperator::doesnt_match: // not superset + case RelationalOperator::equal_icase: // subset + case RelationalOperator::not_equal_icase: // not subset + case RelationalOperator::matches_icase: // contains any + case RelationalOperator::doesnt_match_icase: // contains none of + case RelationalOperator::greater_or_equal: + case RelationalOperator::greater: + return std::nullopt; + } + return std::nullopt; // unreachable +} + +std::optional> IntFilter::valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds /* timezone_offset */) const { + if (column_name != columnName()) { + return {}; // wrong column + } + std::bitset<32> result; + for (int32_t bit = 0; bit < 32; ++bit) { + result[bit] = eval(bit, oper(), _ref_value); + } + return {result}; +} + +std::unique_ptr IntFilter::copy() const { + return std::make_unique(*this); +} + +std::unique_ptr IntFilter::negate() const { + return std::make_unique( + kind(), _column, negateRelationalOperator(oper()), value()); +} diff --git a/src/IntFilter.h b/src/IntFilter.h new file mode 100644 index 0000000..02a2fca --- /dev/null +++ b/src/IntFilter.h @@ -0,0 +1,70 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef IntFilter_h +#define IntFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include "ColumnFilter.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class IntColumn; +class Row; + +class IntFilter : public ColumnFilter { +public: + IntFilter(Kind kind, const IntColumn &column, RelationalOperator relOp, + const std::string &value); + + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::optional greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::optional leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::optional> valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + +private: + const IntColumn &_column; + const int32_t _ref_value; +}; + +#endif // IntFilter_h diff --git a/src/IntPointerColumn.h b/src/IntPointerColumn.h new file mode 100644 index 0000000..706b5f1 --- /dev/null +++ b/src/IntPointerColumn.h @@ -0,0 +1,46 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef IntPointerColumn_h +#define IntPointerColumn_h + +#include "config.h" // IWYU pragma: keep +#include "IntColumn.h" + +class IntPointerColumn : public IntColumn { +public: + IntPointerColumn(const std::string& name, const std::string& description, + const int* number) + : IntColumn(name, description, -1, -1, -1, 0), _number(number) {} + + int32_t getValue(Row /* row */, + const contact* /* auth_user */) const override { + return *_number; + } + +private: + const int* const _number; +}; + +#endif // IntPointerColumn_h diff --git a/src/ListColumn.cc b/src/ListColumn.cc new file mode 100644 index 0000000..b321e5c --- /dev/null +++ b/src/ListColumn.cc @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ListColumn.h" +#include +#include "Filter.h" +#include "ListFilter.h" +#include "Renderer.h" +#include "Row.h" + +void ListColumn::output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const { + ListRenderer l(r); + for (const auto &val : getValue(row, auth_user, timezone_offset)) { + l.output(val); + } +} + +std::unique_ptr ListColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, value); +} + +std::unique_ptr ListColumn::createAggregator( + AggregationFactory /*factory*/) const { + throw std::runtime_error("aggregating on list column '" + name() + + "' not supported"); +} diff --git a/src/ListColumn.h b/src/ListColumn.h new file mode 100644 index 0000000..fed1a71 --- /dev/null +++ b/src/ListColumn.h @@ -0,0 +1,68 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ListColumn_h +#define ListColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class ListColumn : public Column { +public: + ListColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset) + : Column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] ColumnType type() const override { return ColumnType::list; } + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; + + // TODO(sp) What we actually want here is a stream of strings, not a + // concrete container. + virtual std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const = 0; +}; + +#endif // ListColumn_h diff --git a/src/ListFilter.cc b/src/ListFilter.cc new file mode 100644 index 0000000..0a2ff71 --- /dev/null +++ b/src/ListFilter.cc @@ -0,0 +1,145 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ListFilter.h" +#include +#include +#include "Filter.h" +#include "ListColumn.h" +#include "Logger.h" +#include "RegExp.h" +#include "Row.h" + +namespace { +RelationalOperator relOpForElement(RelationalOperator relOp) { + switch (relOp) { + case RelationalOperator::matches: + case RelationalOperator::doesnt_match: + case RelationalOperator::matches_icase: + case RelationalOperator::doesnt_match_icase: + return relOp; + case RelationalOperator::less: + case RelationalOperator::greater_or_equal: + return RelationalOperator::equal; + case RelationalOperator::greater: + case RelationalOperator::less_or_equal: + return RelationalOperator::equal_icase; + case RelationalOperator::equal: + case RelationalOperator::not_equal: + case RelationalOperator::equal_icase: + case RelationalOperator::not_equal_icase: + // optimization: do not create a RegExp later + return RelationalOperator::less; + }; + return relOp; // make the compiler happy... +} +} // namespace + +ListFilter::ListFilter(Kind kind, const ListColumn &column, + RelationalOperator relOp, const std::string &value) + : ColumnFilter(kind, column, relOp, value) + , _column(column) + , _regExp(makeRegExpFor(relOpForElement(relOp), value)) {} + +bool ListFilter::accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const { + switch (oper()) { + case RelationalOperator::equal: + if (!value().empty()) { + Informational(_column.logger()) + << "Sorry, equality for lists implemented only for emptiness"; + return false; + } + return !any(row, auth_user, timezone_offset, + [](const std::string & /*unused*/) { return true; }); + case RelationalOperator::not_equal: + if (!value().empty()) { + Informational(_column.logger()) + << "Sorry, inequality for lists implemented only for emptiness"; + return false; + } + return any(row, auth_user, timezone_offset, + [](const std::string & /*unused*/) { return true; }); + case RelationalOperator::matches: + case RelationalOperator::matches_icase: + return any( + row, auth_user, timezone_offset, + [&](const std::string &elem) { return _regExp->search(elem); }); + case RelationalOperator::doesnt_match: + case RelationalOperator::doesnt_match_icase: + return !any( + row, auth_user, timezone_offset, + [&](const std::string &elem) { return _regExp->search(elem); }); + case RelationalOperator::greater_or_equal: + case RelationalOperator::less_or_equal: + return any( + row, auth_user, timezone_offset, + [&](const std::string &elem) { return _regExp->match(elem); }); + case RelationalOperator::less: + case RelationalOperator::greater: + return !any( + row, auth_user, timezone_offset, + [&](const std::string &elem) { return _regExp->match(elem); }); + case RelationalOperator::equal_icase: + case RelationalOperator::not_equal_icase: + Informational(_column.logger()) + << "Sorry. Operator " << oper() + << " for list columns not implemented."; + return false; + } + return false; // unreachable +} + +std::optional ListFilter::stringValueRestrictionFor( + const std::string &column_name) const { + if (column_name != columnName()) { + return {}; // wrong column + } + switch (oper()) { + case RelationalOperator::greater_or_equal: + return {value()}; + case RelationalOperator::equal: + case RelationalOperator::not_equal: + case RelationalOperator::matches: + case RelationalOperator::doesnt_match: + case RelationalOperator::equal_icase: + case RelationalOperator::not_equal_icase: + case RelationalOperator::matches_icase: + case RelationalOperator::doesnt_match_icase: + case RelationalOperator::less: + case RelationalOperator::greater: + case RelationalOperator::less_or_equal: + return {}; + } + return {}; // unreachable +} + +std::unique_ptr ListFilter::copy() const { + return std::make_unique(*this); +} + +std::unique_ptr ListFilter::negate() const { + return std::make_unique( + kind(), _column, negateRelationalOperator(oper()), value()); +} diff --git a/src/ListFilter.h b/src/ListFilter.h new file mode 100644 index 0000000..df6ef1d --- /dev/null +++ b/src/ListFilter.h @@ -0,0 +1,66 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ListFilter_h +#define ListFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include "ColumnFilter.h" +#include "Filter.h" +#include "ListColumn.h" +#include "Row.h" +#include "contact_fwd.h" +#include "opids.h" +class RegExp; + +class ListFilter : public ColumnFilter { +public: + ListFilter(Kind kind, const ListColumn &column, RelationalOperator relOp, + const std::string &value); + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::optional stringValueRestrictionFor( + const std::string &column_name) const override; + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + +private: + const ListColumn &_column; + std::shared_ptr _regExp; + + template + bool any(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset, UnaryPredicate pred) const { + auto val = _column.getValue(row, auth_user, timezone_offset); + return std::any_of(val.begin(), val.end(), pred); + } +}; + +#endif // ListFilter_h diff --git a/src/LogCache.cc b/src/LogCache.cc new file mode 100644 index 0000000..ad96afd --- /dev/null +++ b/src/LogCache.cc @@ -0,0 +1,206 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "LogCache.h" +#include +#include +#include +#include "FileSystem.h" +#include "LogEntry.h" // IWYU pragma: keep +#include "Logfile.h" +#include "Logger.h" +#include "MonitoringCore.h" + +namespace { +// Check memory every N'th new message +constexpr unsigned long check_mem_cycle = 1000; +} // namespace + +int num_cached_log_messages = 0; + +LogCache::LogCache(MonitoringCore *mc, unsigned long max_cached_messages) + : _mc(mc) + , _max_cached_messages(max_cached_messages) + , _num_at_last_check(0) { + update(); +} + +#ifdef CMC +void LogCache::setMaxCachedMessages(unsigned long m) { + if (m != _max_cached_messages) { + Notice(logger()) + << "changing maximum number of messages for log file cache to " + << m; + _max_cached_messages = m; + } +} +#endif + +void LogCache::update() { + if (!_logfiles.empty() && + _mc->last_logfile_rotation() <= _last_index_update) { + return; + } + + Informational(logger()) << "updating log file index"; + + _logfiles.clear(); + num_cached_log_messages = 0; + + _last_index_update = std::chrono::system_clock::now(); + // We need to find all relevant logfiles. This includes directory, the + // current nagios.log and all files in the archive. + addToIndex( + std::make_unique(_mc, this, _mc->historyFilePath(), true)); + + fs::path dirpath = _mc->logArchivePath(); + try { + for (const auto &entry : fs::directory_iterator(dirpath)) { + addToIndex( + std::make_unique(_mc, this, entry.path(), false)); + } + } catch (const fs::filesystem_error &e) { + Warning(logger()) << "updating log file index: " << e.what(); + } + + if (_logfiles.empty()) { + Notice(logger()) << "no log file found, not even " + << _mc->historyFilePath(); + } +} + +void LogCache::addToIndex(std::unique_ptr logfile) { + time_t since = logfile->since(); + if (since == 0) { + return; + } + // make sure that no entry with that 'since' is existing yet. Under normal + // circumstances this never happens, but the user might have copied files + // around. + if (_logfiles.find(since) != _logfiles.end()) { + Warning(logger()) << "ignoring duplicate log file " << logfile->path(); + return; + } + + _logfiles.emplace(since, std::move(logfile)); +} + +/* This method is called each time a log message is loaded + into memory. If the number of messages loaded in memory + is to large, memory will be freed by flushing logfiles + and message not needed by the current query. + + The parameters to this method reflect the current query, + not the messages that just has been loaded. + */ +void LogCache::logLineHasBeenAdded(Logfile *logfile, unsigned logclasses) { + if (static_cast(++num_cached_log_messages) <= + _max_cached_messages) { + return; // current message count still allowed, everything ok + } + + /* Memory checking an freeing consumes CPU ressources. We save + ressources, by avoiding to make the memory check each time + a new message is loaded when being in a sitation where no + memory can be freed. We do this by suppressing the check when + the number of messages loaded into memory has not grown + by at least check_mem_cycle messages */ + if (static_cast(num_cached_log_messages) < + _num_at_last_check + check_mem_cycle) { + return; // Do not check this time + } + + // [1] Begin by deleting old logfiles + // Begin deleting with the oldest logfile available + logfiles_t::iterator it; + for (it = _logfiles.begin(); it != _logfiles.end(); ++it) { + if (it->second.get() == logfile) { + // Do not touch the logfile the Query is currently accessing + break; + } + if (it->second->size() > 0) { + num_cached_log_messages -= it->second->size(); + it->second->flush(); // drop all messages of that file + if (static_cast(num_cached_log_messages) <= + _max_cached_messages) { + // remember the number of log messages in cache when + // the last memory-release was done. No further + // release-check shall be done until that number changes. + _num_at_last_check = num_cached_log_messages; + return; + } + } + } + // The end of this loop must be reached by 'break'. At least one logfile + // must be the current logfile. So now 'it' points to the current logfile. + // We save that pointer for later. + auto queryit = it; + + // [2] Delete message classes irrelevent to current query + // Starting from the current logfile (wo broke out of the + // previous loop just when 'it' pointed to that) + for (; it != _logfiles.end(); ++it) { + if (it->second->size() > 0 && + (it->second->classesRead() & ~logclasses) != 0) { + Debug(logger()) << "freeing classes " << ~logclasses << " of file " + << it->second->path(); + // flush only messages not needed for current query + long freed = it->second->freeMessages(~logclasses); + num_cached_log_messages -= freed; + if (static_cast(num_cached_log_messages) <= + _max_cached_messages) { + _num_at_last_check = num_cached_log_messages; + return; + } + } + } + + // [3] Flush newest logfiles + // If there are still too many messages loaded, continue + // flushing logfiles from the oldest to the newest starting + // at the file just after (i.e. newer than) the current logfile + for (it = ++queryit; it != _logfiles.end(); ++it) { + if (it->second->size() > 0) { + Debug(logger()) << "flush newer log, " << it->second->size() + << " number of entries"; + num_cached_log_messages -= it->second->size(); + it->second->flush(); + if (static_cast(num_cached_log_messages) <= + _max_cached_messages) { + _num_at_last_check = num_cached_log_messages; + return; + } + } + } + _num_at_last_check = num_cached_log_messages; + // If we reach this point, no more logfiles can be unloaded, + // despite the fact that there are still too many messages + // loaded. + + Debug(logger()) << "cannot unload more messages, still " + << num_cached_log_messages << " loaded (max is " + << _max_cached_messages << ")"; +} + +Logger *LogCache::logger() const { return _mc->loggerLivestatus(); } diff --git a/src/LogCache.h b/src/LogCache.h new file mode 100644 index 0000000..3016b80 --- /dev/null +++ b/src/LogCache.h @@ -0,0 +1,64 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef LogCache_h +#define LogCache_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +class Logfile; +class Logger; +class MonitoringCore; + +using logfiles_t = std::map>; + +class LogCache { +public: + std::mutex _lock; + + LogCache(MonitoringCore *mc, unsigned long max_cached_messages); +#ifdef CMC + void setMaxCachedMessages(unsigned long m); +#endif + void logLineHasBeenAdded(Logfile *logfile, unsigned logclasses); + void update(); + auto begin() { return _logfiles.begin(); } + auto end() { return _logfiles.end(); } + +private: + MonitoringCore *const _mc; + unsigned long _max_cached_messages; + unsigned long _num_at_last_check; + logfiles_t _logfiles; + std::chrono::system_clock::time_point _last_index_update; + + void addToIndex(std::unique_ptr logfile); + [[nodiscard]] Logger *logger() const; +}; + +#endif // LogCache_h diff --git a/src/LogEntry.cc b/src/LogEntry.cc new file mode 100644 index 0000000..e907a02 --- /dev/null +++ b/src/LogEntry.cc @@ -0,0 +1,417 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "LogEntry.h" +#include +#include +#include +#include +#include "MonitoringCore.h" + +// 0123456789012345678901234567890 +// [1234567890] FOO BAR: blah blah +static constexpr size_t timestamp_prefix_length = 13; + +// TODO(sp) Fix classifyLogMessage() below to always set all fields and remove +// this set-me-to-zero-to-be-sure-block. +LogEntry::LogEntry(MonitoringCore *mc, size_t lineno, std::string line) + : _lineno(static_cast(lineno)) + , _complete(std::move(line)) + , _state(0) + , _attempt(0) + , _host(nullptr) + , _service(nullptr) + , _contact(nullptr) { + // pointer to options (everything after ':') + size_t pos = _complete.find(':'); + if (pos != std::string::npos) { + pos = _complete.find_first_not_of(' ', pos + 1); + } + if (pos == std::string::npos) { + pos = _complete.size(); + } + _options = &_complete[pos]; + + try { + if (_complete.size() < timestamp_prefix_length || _complete[0] != '[' || + _complete[11] != ']' || _complete[12] != ' ') { + throw std::invalid_argument("timestamp delimiter"); + } + _time = std::stoi(_complete.substr(1, 10)); + } catch (const std::logic_error &e) { + _logclass = Class::invalid; + _type = LogEntryType::none; + return; // ignore invalid lines silently + } + + classifyLogMessage(); + applyWorkarounds(); + updateReferences(mc); +} + +bool LogEntry::assign(Param par, const std::string &field) { + switch (par) { + case Param::HostName: + this->_host_name = field; + break; + case Param::SvcDesc: + this->_svc_desc = field; + break; + case Param::HostState: + this->_state = static_cast(parseHostState(field)); + break; + case Param::ServiceState: + this->_state = static_cast(parseServiceState(field)); + break; + case Param::State: + this->_state = atoi(field.c_str()); + break; + case Param::StateType: + this->_state_type = field; + break; + case Param::Attempt: + this->_attempt = atoi(field.c_str()); + break; + case Param::Comment: + this->_comment = field; + break; + case Param::CommandName: + this->_command_name = field; + break; + case Param::ContactName: + this->_contact_name = field; + break; + case Param::CheckOutput: + this->_check_output = field; + break; + } + + return true; +}; + +std::vector LogEntry::log_definitions{ + LogDef{"INITIAL HOST STATE", + Class::state, + LogEntryType::state_host_initial, + {Param::HostName, Param::HostState, Param::StateType, Param::Attempt, + Param::CheckOutput}}, + //////////////// + LogDef{"CURRENT HOST STATE", + Class::state, + LogEntryType::state_host, + {Param::HostName, Param::HostState, Param::StateType, Param::Attempt, + Param::CheckOutput}}, + //////////////// + LogDef{"HOST ALERT", + Class::alert, + LogEntryType::alert_host, + {Param::HostName, Param::HostState, Param::StateType, Param::Attempt, + Param::CheckOutput}}, + //////////////// + LogDef{"HOST DOWNTIME ALERT", + Class::alert, + LogEntryType::downtime_alert_host, + {Param::HostName, Param::StateType, Param::Comment}}, + //////////////// + LogDef{"HOST ACKNOWLEDGE ALERT", + Class::alert, + LogEntryType::acknowledge_alert_host, + {Param::HostName, Param::StateType, Param::ContactName, + Param::Comment}}, + //////////////// + LogDef{"HOST FLAPPING ALERT", + Class::alert, + LogEntryType::flapping_host, + {Param::HostName, Param::StateType, Param::Comment}}, + //////////////// + LogDef{"INITIAL SERVICE STATE", + Class::state, + LogEntryType::state_service_initial, + {Param::HostName, Param::SvcDesc, Param::ServiceState, + Param::StateType, Param::Attempt, Param::CheckOutput}}, + //////////////// + LogDef{"CURRENT SERVICE STATE", + Class::state, + LogEntryType::state_service, + {Param::HostName, Param::SvcDesc, Param::ServiceState, + Param::StateType, Param::Attempt, Param::CheckOutput}}, + //////////////// + LogDef{"SERVICE ALERT", + Class::alert, + LogEntryType::alert_service, + {Param::HostName, Param::SvcDesc, Param::ServiceState, + Param::StateType, Param::Attempt, Param::CheckOutput}}, + //////////////// + LogDef{"SERVICE DOWNTIME ALERT", + Class::alert, + LogEntryType::downtime_alert_service, + {Param::HostName, Param::SvcDesc, Param::StateType, Param::Comment}}, + //////////////// + LogDef{"SERVICE ACKNOWLEDGE ALERT", + Class::alert, + LogEntryType::acknowledge_alert_service, + {Param::HostName, Param::SvcDesc, Param::StateType, + Param::ContactName, Param::Comment}}, + //////////////// + LogDef{"SERVICE FLAPPING ALERT", + Class::alert, + LogEntryType::flapping_service, + {Param::HostName, Param::SvcDesc, Param::StateType, Param::Comment}}, + //////////////// + LogDef{"TIMEPERIOD TRANSITION", + Class::state, + LogEntryType::timeperiod_transition, + {}}, + //////////////// + LogDef{"HOST NOTIFICATION", + Class::hs_notification, + LogEntryType::none, + {Param::ContactName, Param::HostName, Param::StateType, + Param::CommandName, Param::CheckOutput}}, + //////////////// + LogDef{"SERVICE NOTIFICATION", + Class::hs_notification, + LogEntryType::none, + {Param::ContactName, Param::HostName, Param::SvcDesc, + Param::StateType, Param::CommandName, Param::CheckOutput}}, + //////////////// + LogDef{"HOST NOTIFICATION RESULT", + Class::hs_notification, + LogEntryType::none, + {Param::ContactName, Param::HostName, Param::StateType, + Param::CommandName, Param::CheckOutput, Param::Comment}}, + //////////////// + LogDef{ + "SERVICE NOTIFICATION RESULT", + Class::hs_notification, + LogEntryType::none, + {Param::ContactName, Param::HostName, Param::SvcDesc, Param::StateType, + Param::CommandName, Param::CheckOutput, Param::Comment}}, + //////////////// + LogDef{"HOST NOTIFICATION PROGRESS", + Class::hs_notification, + LogEntryType::none, + {Param::ContactName, Param::HostName, Param::StateType, + Param::CommandName, Param::CheckOutput}}, + //////////////// + LogDef{"SERVICE NOTIFICATION PROGRESS", + Class::hs_notification, + LogEntryType::none, + {Param::ContactName, Param::HostName, Param::SvcDesc, + Param::StateType, Param::CommandName, Param::CheckOutput}}, + //////////////// + LogDef{"HOST ALERT HANDLER STARTED", + Class::alert_handlers, + LogEntryType::none, + {Param::HostName, Param::CommandName}}, + //////////////// + LogDef{"SERVICE ALERT HANDLER STARTED", + Class::alert_handlers, + LogEntryType::none, + {Param::HostName, Param::SvcDesc, Param::CommandName}}, + //////////////// + LogDef{"HOST ALERT HANDLER STOPPED", + Class::alert_handlers, + LogEntryType::none, + {Param::HostName, Param::CommandName, Param::ServiceState, + Param::CheckOutput}}, + //////////////// + LogDef{"SERVICE ALERT HANDLER STOPPED", + Class::alert_handlers, + LogEntryType::none, + {Param::HostName, Param::SvcDesc, Param::CommandName, + Param::ServiceState, Param::CheckOutput}}, + //////////////// + LogDef{"PASSIVE SERVICE CHECK", + Class::passivecheck, + LogEntryType::none, + {Param::HostName, Param::SvcDesc, Param::State, Param::CheckOutput}}, + //////////////// + LogDef{"PASSIVE HOST CHECK", + Class::passivecheck, + LogEntryType::none, + {Param::HostName, Param::State, Param::CheckOutput}}, + //////////////// + LogDef{"EXTERNAL COMMAND", Class::ext_command, LogEntryType::none, {}}}; + +// A bit verbose, but we avoid unnecessary string copies below. +void LogEntry::classifyLogMessage() { + for (const auto &def : log_definitions) { + if (textStartsWith(def.prefix) && + _complete.compare(timestamp_prefix_length + def.prefix.size(), 2, + ": ") == 0) { + _text = &def.prefix[0]; + _logclass = def.log_class; + _type = def.log_type; + // TODO(sp) Use boost::tokenizer instead of this index fiddling + size_t pos = timestamp_prefix_length + def.prefix.size() + 2; + for (Param par : def.params) { + size_t sep_pos = _complete.find(';', pos); + size_t end_pos = + sep_pos == std::string::npos ? _complete.size() : sep_pos; + assign(par, _complete.substr(pos, end_pos - pos)); + pos = sep_pos == std::string::npos ? _complete.size() + : (sep_pos + 1); + } + return; + } + } + _text = &_complete[timestamp_prefix_length]; + if (textStartsWith("LOG VERSION: 2.0")) { + _logclass = Class::program; + _type = LogEntryType::log_version; + return; + } + if (textStartsWith("logging initial states") || + textStartsWith("logging intitial states")) { + _logclass = Class::program; + _type = LogEntryType::log_initial_states; + return; + } + if (textContains("starting...") || textContains("active mode...")) { + _logclass = Class::program; + _type = LogEntryType::core_starting; + return; + } + if (textContains("shutting down...") || textContains("Bailing out") || + textContains("standby mode...")) { + _logclass = Class::program; + _type = LogEntryType::core_stopping; + return; + } + if (textContains("restarting...")) { + _logclass = Class::program; + _type = LogEntryType::none; + return; + } + _logclass = Class::info; + _type = LogEntryType::none; +} + +bool LogEntry::textStartsWith(const std::string &what) { + return _complete.compare(timestamp_prefix_length, what.size(), what) == 0; +} + +bool LogEntry::textContains(const std::string &what) { + return _complete.find(what, timestamp_prefix_length) != std::string::npos; +} + +// The NotifyHelper class has a long, tragic history: Through a long series of +// commits, it suffered from spelling mistakes like "HOST_NOTIFICATION" or "HOST +// NOTIFICATION" (without a colon), parameter lists not matching the +// corresponding format strings, and last but not least wrong ordering of +// fields. The net result of this tragedy is that due to legacy reasons, we have +// to support parsing an incorrect ordering of "state type" and "command name" +// fields. :-P +void LogEntry::applyWorkarounds() { + if (_logclass != Class::hs_notification || // no need for any workaround + _state_type.empty()) { // extremely broken line + return; + } + + if (_state_type == "check-mk-notify") { + // Ooops, we encounter one of our own buggy lines... + std::swap(_state_type, _command_name); + } + + if (_state_type.empty()) { + return; // extremely broken line, even after a potential swap + } + + _state = _svc_desc.empty() + ? static_cast(parseHostState(_state_type)) + : static_cast(parseServiceState(_state_type)); +} + +namespace { +// Ugly: Depending on where we're called, the actual state type can be in +// parentheses at the end, e.g. "ALERTHANDLER (OK)". +std::string extractStateType(const std::string &str) { + if (!str.empty() && str[str.size() - 1] == ')') { + size_t lparen = str.rfind('('); + if (lparen != std::string::npos) { + return str.substr(lparen + 1, str.size() - lparen - 2); + } + } + return str; +} + +std::unordered_map serviceStateTypes{ + // normal states + {"OK", ServiceState::ok}, + {"WARNING", ServiceState::warning}, + {"CRITICAL", ServiceState::critical}, + {"UNKNOWN", ServiceState::unknown}, + // states from "... ALERT"/"... NOTIFICATION" + {"RECOVERY", ServiceState::ok}}; + +std::unordered_map hostStateTypes{ + // normal states + {"UP", HostState::up}, + {"DOWN", HostState::down}, + {"UNREACHABLE", HostState::unreachable}, + // states from "... ALERT"/"... NOTIFICATION" + {"RECOVERY", HostState::up}, + // states from "... ALERT HANDLER STOPPED" and "(HOST|SERVICE) NOTIFICATION + // (RESULT|PROGRESS)" + {"OK", HostState::up}, + {"WARNING", HostState::down}, + {"CRITICAL", HostState::unreachable}, + {"UNKNOWN", HostState::up}}; +} // namespace + +ServiceState LogEntry::parseServiceState(const std::string &str) { + auto it = serviceStateTypes.find(extractStateType(str)); + return it == serviceStateTypes.end() ? ServiceState::ok : it->second; +} + +HostState LogEntry::parseHostState(const std::string &str) { + auto it = hostStateTypes.find(extractStateType(str)); + return it == hostStateTypes.end() ? HostState::up : it->second; +} + +unsigned LogEntry::updateReferences(MonitoringCore *mc) { + unsigned updated = 0; + if (!_host_name.empty()) { + // Older Nagios headers are not const-correct... :-P + _host = find_host(const_cast(_host_name.c_str())); + updated++; + } + if (!_svc_desc.empty()) { + // Older Nagios headers are not const-correct... :-P + _service = find_service(const_cast(_host_name.c_str()), + const_cast(_svc_desc.c_str())); + updated++; + } + if (!_contact_name.empty()) { + // Older Nagios headers are not const-correct... :-P + _contact = find_contact(const_cast(_contact_name.c_str())); + updated++; + } + if (!_command_name.empty()) { + _command = mc->find_command(_command_name); + updated++; + } + return updated; +} diff --git a/src/LogEntry.h b/src/LogEntry.h new file mode 100644 index 0000000..32ffb16 --- /dev/null +++ b/src/LogEntry.h @@ -0,0 +1,166 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef LogEntry_h +#define LogEntry_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "MonitoringCore.h" +#include "nagios.h" + +enum class ServiceState { ok = 0, warning = 1, critical = 2, unknown = 3 }; + +inline double badness(ServiceState state) { + // unknown is effectively between warning and critical + return state == ServiceState::unknown + ? (static_cast(ServiceState::warning) + + static_cast(ServiceState::critical)) / + 2.0 + : static_cast(state); +} + +inline bool worse(ServiceState state1, ServiceState state2) { + return badness(state1) > badness(state2); +} + +enum class HostState { up = 0, down = 1, unreachable = 2 }; + +inline double badness(HostState state) { + // unreachable is effectively between up and down + return state == HostState::unreachable + ? (static_cast(HostState::up) + + static_cast(HostState::down)) / + 2.0 + : static_cast(state); +} + +inline bool worse(HostState state1, HostState state2) { + return badness(state1) > badness(state2); +} + +enum class LogEntryType { + none, + alert_host, + alert_service, + downtime_alert_host, + downtime_alert_service, + state_host, + state_host_initial, + state_service, + state_service_initial, + flapping_host, + flapping_service, + timeperiod_transition, + core_starting, + core_stopping, + log_version, + log_initial_states, + acknowledge_alert_host, + acknowledge_alert_service +}; + +class LogEntry { +public: + enum class Class { + info = 0, // all messages not in any other class + alert = 1, // alerts: the change service/host state + program = 2, // important programm events (restart, ...) + hs_notification = 3, // host/service notifications + passivecheck = 4, // passive checks + ext_command = 5, // external commands + state = 6, // initial or current states + text = 7, // specific text passages + alert_handlers = 8, // Started and stopped alert handlers + + // TODO(sp): This class sets different logclasses on match -> fix this + invalid = 0x7fffffff // never stored + }; + static constexpr uint32_t all_classes = 0xffffU; + + // TODO(sp): Wrong type, caused by TableLog accessing it via + // OffsetIntColumn, should be size_t + int _lineno; // line number in file + time_t _time; + Class _logclass; + LogEntryType _type; + std::string _complete; // copy of complete unsplit message + const char *_options; // points into _complete after ':' + const char *_text; // points into _complete or into static data + std::string _host_name; + std::string _svc_desc; + std::string _command_name; + std::string _contact_name; + int _state; + std::string _state_type; + int _attempt; + std::string _check_output; + std::string _comment; + + host *_host; + service *_service; + contact *_contact; + Command _command; + + // NOTE: line gets modified! + LogEntry(MonitoringCore *mc, size_t lineno, std::string line); + unsigned updateReferences(MonitoringCore *mc); + static ServiceState parseServiceState(const std::string &str); + static HostState parseHostState(const std::string &str); + +private: + enum class Param { + HostName, + SvcDesc, + CommandName, + ContactName, + HostState, + ServiceState, + State, + StateType, + Attempt, + Comment, + CheckOutput + }; + + struct LogDef { + std::string prefix; + Class log_class; + LogEntryType log_type; + std::vector params; + }; + + static std::vector log_definitions; + + bool assign(Param par, const std::string &field); + void applyWorkarounds(); + void classifyLogMessage(); + bool textStartsWith(const std::string &what); + bool textContains(const std::string &what); +}; + +#endif // LogEntry_h diff --git a/src/Logfile.cc b/src/Logfile.cc new file mode 100644 index 0000000..6ac67b5 --- /dev/null +++ b/src/Logfile.cc @@ -0,0 +1,252 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +// https://github.com/include-what-you-use/include-what-you-use/issues/166 +// IWYU pragma: no_include +#include "Logfile.h" +#include +#include +#include +#include +#include +#include "LogCache.h" +#include "LogEntry.h" +#include "Logger.h" +#include "MonitoringCore.h" +#include "Query.h" +#include "Row.h" + +#ifdef CMC +#include "cmc.h" +#endif + +namespace { +time_t firstTimestampOf(const fs::path &path, Logger *logger) { + std::ifstream is(path, std::ios::binary); + if (!is) { + generic_error ge("cannot open logfile " + path.string()); + Informational(logger) << ge; + return 0; + } + + char line[12]; + is.read(line, sizeof(line)); + if (!is) { + return 0; // ignoring. might be empty + } + + if (line[0] != '[' || line[11] != ']') { + Informational(logger) << "ignoring logfile '" << path + << "': does not begin with '[123456789] '"; + return 0; + } + + line[11] = 0; + return atoi(line + 1); +} +} // namespace + +Logfile::Logfile(MonitoringCore *mc, LogCache *logcache, fs::path path, + bool watch) + : _mc(mc) + , _logcache(logcache) + , _path(std::move(path)) + , _since(firstTimestampOf(_path, logger())) + , _watch(watch) + , _read_pos{} + , _lineno(0) +#ifdef CMC + , _world(nullptr) +#endif + , _logclasses_read(0) { +} + +void Logfile::flush() { + _entries.clear(); + _logclasses_read = 0; +} + +void Logfile::load(unsigned logclasses) { + unsigned missing_types = logclasses & ~_logclasses_read; + // The current logfile has the _watch flag set to true. + // In that case, if the logfile has grown, we need to + // load the rest of the file, even if no logclasses + // are missing. + if (_watch) { + FILE *file = fopen(_path.c_str(), "r"); + if (file == nullptr) { + generic_error ge("cannot open logfile " + _path.string()); + Informational(logger()) << ge; + return; + } + // If we read this file for the first time, we initialize + // the current file position to 0 + if (_lineno == 0) { + fgetpos(file, &_read_pos); + } + + // file might have grown. Read all classes that we already + // have read to the end of the file + if (_logclasses_read != 0U) { + fsetpos(file, &_read_pos); // continue at previous end + loadRange(file, _logclasses_read, logclasses); + fgetpos(file, &_read_pos); + } + if (missing_types != 0U) { + fseek(file, 0, SEEK_SET); + _lineno = 0; + loadRange(file, missing_types, logclasses); + _logclasses_read |= missing_types; + fgetpos(file, &_read_pos); // remember current end of file + } + fclose(file); + } else { + if (missing_types == 0) { + return; + } + + FILE *file = fopen(_path.c_str(), "r"); + if (file == nullptr) { + generic_error ge("cannot open logfile " + _path.string()); + Informational(logger()) << ge; + return; + } + + _lineno = 0; + loadRange(file, missing_types, logclasses); + _logclasses_read |= missing_types; + fclose(file); + } +} + +void Logfile::loadRange(FILE *file, unsigned missing_types, + unsigned logclasses) { + std::vector linebuffer(65536); + // TODO(sp) We should really use C++ I/O here... + while (fgets(&linebuffer[0], static_cast(linebuffer.size()), file) != + nullptr) { + if (_lineno >= _mc->maxLinesPerLogFile()) { + Error(logger()) << "more than " << _mc->maxLinesPerLogFile() + << " lines in " << _path << ", ignoring the rest!"; + return; + } + _lineno++; + // remove trailing newline (should be nuked, see above) + for (auto &ch : linebuffer) { + if (ch == '\0' || ch == '\n') { + ch = '\0'; + break; + } + } + if (processLogLine(_lineno, &linebuffer[0], missing_types)) { + _logcache->logLineHasBeenAdded(this, logclasses); + } + } +} + +long Logfile::freeMessages(unsigned logclasses) { + long freed = 0; + // We have to be careful here: Erasing an element from an associative + // container invalidates the iterator pointing to it. The solution is the + // usual post-increment idiom, see Scott Meyers' "Effective STL", item 9 + // ("Choose carefully among erasing options."). + for (auto it = _entries.begin(); it != _entries.end();) { + if (((1U << static_cast(it->second->_logclass)) & logclasses) != + 0U) { + _entries.erase(it++); + freed++; + } else { + ++it; + } + } + _logclasses_read &= ~logclasses; + return freed; +} + +bool Logfile::processLogLine(size_t lineno, std::string line, + unsigned logclasses) { + auto entry = std::make_unique(_mc, lineno, std::move(line)); + // ignored invalid lines + if (entry->_logclass == LogEntry::Class::invalid) { + return false; + } + if (((1U << static_cast(entry->_logclass)) & logclasses) == 0U) { + return false; + } + uint64_t key = makeKey(entry->_time, entry->_lineno); + if (_entries.find(key) != _entries.end()) { + // this should never happen. The lineno must be unique! + Error(logger()) << "strange duplicate logfile line " + << entry->_complete; + return false; + } + _entries[key] = std::move(entry); + return true; +} + +const logfile_entries_t *Logfile::getEntriesFor(unsigned logclasses) { + // Make sure existing references to objects point to correct world + updateReferences(); + // make sure all messages are present + load(logclasses); + return &_entries; +} + +bool Logfile::answerQueryReverse(Query *query, time_t since, time_t until, + unsigned logclasses) { + auto entries = getEntriesFor(logclasses); + // TODO(sp) Move the stuff below out of this class. Tricky part: makeKey + auto it = entries->upper_bound(makeKey(until, 999999999)); + while (it != entries->begin()) { + --it; + // end found or limit exceeded? + if (it->second->_time < since || + !query->processDataset(Row(it->second.get()))) { + return false; + } + } + return true; +} + +uint64_t Logfile::makeKey(time_t t, size_t lineno) { + return (static_cast(t) << 32) | static_cast(lineno); +} + +void Logfile::updateReferences() { +#ifdef CMC + // If our references in cached log entries do not point to the currently + // active configuration world, then update all references + if (_world != g_live_world) { + unsigned num = 0; + for (auto &entry : _entries) { + num += entry.second->updateReferences(_mc); + } + Notice(logger()) << "updated " << num << " log cache references of " + << _path << " to new world."; + _world = g_live_world; + } +#endif +} + +Logger *Logfile::logger() const { return _mc->loggerLivestatus(); } diff --git a/src/Logfile.h b/src/Logfile.h new file mode 100644 index 0000000..20f7225 --- /dev/null +++ b/src/Logfile.h @@ -0,0 +1,90 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Logfile_h +#define Logfile_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include "FileSystem.h" +class LogCache; +class LogEntry; +class Logger; +class MonitoringCore; +class Query; + +#ifdef CMC +class World; +#endif + +// key is time_t . lineno +using logfile_entries_t = std::map>; + +class Logfile { +public: + Logfile(MonitoringCore *mc, LogCache *logcache, fs::path path, bool watch); + [[nodiscard]] fs::path path() const { return _path; } + + // for tricky protocol between LogCache::logLineHasBeenAdded and this class + void flush(); + [[nodiscard]] time_t since() const { return _since; } + [[nodiscard]] unsigned classesRead() const { return _logclasses_read; } + [[nodiscard]] size_t size() const { return _entries.size(); } + long freeMessages(unsigned logclasses); + + // for TableStateHistory + const logfile_entries_t *getEntriesFor(unsigned logclasses); + + // for TableLog::answerQuery + bool answerQueryReverse(Query *query, time_t since, time_t until, + unsigned logclasses); + +private: + MonitoringCore *const _mc; + LogCache *const _logcache; + const fs::path _path; + const time_t _since; // time of first entry + const bool _watch; // true only for current logfile + fpos_t _read_pos; // read until this position + size_t _lineno; // read until this line + logfile_entries_t _entries; +#ifdef CMC + World *_world; // CMC: world our references point into +#endif + unsigned _logclasses_read; // only these types have been read + + void load(unsigned logclasses); + void loadRange(FILE *file, unsigned missing_types, unsigned logclasses); + bool processLogLine(size_t lineno, std::string line, unsigned logclasses); + uint64_t makeKey(time_t t, size_t lineno); + void updateReferences(); + [[nodiscard]] Logger *logger() const; +}; + +#endif // Logfile_h diff --git a/src/Logger.cc b/src/Logger.cc new file mode 100644 index 0000000..adfd8bc --- /dev/null +++ b/src/Logger.cc @@ -0,0 +1,192 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Logger.h" +#include +#include +#include +#include "ChronoUtils.h" + +// ----------------------------------------------------------------------------- + +std::ostream &operator<<(std::ostream &os, const LogLevel &c) { + return os << static_cast(c); +} + +// ----------------------------------------------------------------------------- + +void SimpleFormatter::format(std::ostream &os, const LogRecord &record) { + os << FormattedTimePoint(record.getTimePoint()) << // + " [" << record.getLevel() << "] " << record.getMessage(); +} + +SharedStreamHandler::SharedStreamHandler(std::mutex &mutex, std::ostream &os) + : _mutex(mutex), _os(os) {} + +void SharedStreamHandler::publish(const LogRecord &record) { + std::lock_guard lg(_mutex); + getFormatter()->format(_os, record); + _os << std::endl; +} + +StreamHandler::StreamHandler(std::ostream &os) + : SharedStreamHandler(_mutex, os) {} + +FileHandler::FileHandler(const std::string &filename) : StreamHandler(_os) { + _os.open(filename, std::ofstream::app); + if (!_os) { + throw generic_error("could not open logfile " + filename); + } +} + +// ----------------------------------------------------------------------------- + +// static +Logger *Logger::getLogger(const std::string &name) { + return LogManager::getLogManager()->getLogger(name); +} + +bool Logger::isLoggable(LogLevel level) const { return level <= getLevel(); } + +ConcreteLogger::ConcreteLogger(const std::string &name, Logger *parent) + : _name(name) + , _parent(parent) + , _level(LogLevel::debug) + , _handler(name.empty() ? nullptr : new StreamHandler(std::cerr)) + , _use_parent_handlers(true) {} + +ConcreteLogger::~ConcreteLogger() { delete _handler; } + +std::string ConcreteLogger::getName() const { return _name; } + +Logger *ConcreteLogger::getParent() const { return _parent; } + +LogLevel ConcreteLogger::getLevel() const { return _level; } + +void ConcreteLogger::setLevel(LogLevel level) { _level = level; } + +Handler *ConcreteLogger::getHandler() const { return _handler; } + +void ConcreteLogger::setHandler(std::unique_ptr handler) { + delete _handler; + _handler = handler.release(); +} + +bool ConcreteLogger::getUseParentHandlers() const { + return _use_parent_handlers; +} +void ConcreteLogger::setUseParentHandlers(bool useParentHandlers) { + _use_parent_handlers = useParentHandlers; +} + +void ConcreteLogger::emitContext(std::ostream & /*unused*/) const {} + +void ConcreteLogger::log(const LogRecord &record) { + if (!isLoggable(record.getLevel())) { + return; + } + for (Logger *logger = this; logger != nullptr; + logger = logger->getParent()) { + if (Handler *handler = logger->getHandler()) { + handler->publish(record); + } + if (!logger->getUseParentHandlers()) { + break; + } + } +} + +LoggerDecorator::LoggerDecorator(Logger *logger) : _logger(logger) {} + +std::string LoggerDecorator::getName() const { return _logger->getName(); } + +Logger *LoggerDecorator::getParent() const { return _logger->getParent(); } + +LogLevel LoggerDecorator::getLevel() const { return _logger->getLevel(); } + +void LoggerDecorator::setLevel(LogLevel level) { _logger->setLevel(level); } + +Handler *LoggerDecorator::getHandler() const { return _logger->getHandler(); } + +void LoggerDecorator::setHandler(std::unique_ptr handler) { + _logger->setHandler(std::move(handler)); +} + +bool LoggerDecorator::getUseParentHandlers() const { + return _logger->getUseParentHandlers(); +} + +void LoggerDecorator::setUseParentHandlers(bool useParentHandlers) { + _logger->setUseParentHandlers(useParentHandlers); +} + +void LoggerDecorator::emitContext(std::ostream &os) const { + _logger->emitContext(os); +} + +void LoggerDecorator::log(const LogRecord &record) { _logger->log(record); } + +void ContextLogger::emitContext(std::ostream &os) const { + _logger->emitContext(os); + _context(os); +} + +// ----------------------------------------------------------------------------- + +Logger *LogManager::getLogger(const std::string &name) { + Logger *current = lookup("", nullptr); + for (size_t pos = 0; pos <= name.size();) { + size_t dot = name.find('.', pos); + if (dot == std::string::npos) { + dot = name.size(); + } + if (dot != pos) { + current = lookup( + (current->getName().empty() ? "" : (current->getName() + ".")) + + name.substr(pos, dot - pos), + current); + } + pos = dot + 1; + } + return current; +} + +Logger *LogManager::lookup(const std::string &name, Logger *parent) { + std::lock_guard lg(_mutex); + auto it = _known_loggers.find(name); + if (it == _known_loggers.end()) { + it = _known_loggers + .emplace(name, std::make_unique(name, parent)) + .first; + } + return it->second.get(); +} + +LogManager LogManager::_global_log_manager; + +// ----------------------------------------------------------------------------- + +std::ostream &operator<<(std::ostream &os, const generic_error &ge) { + return os << ge.what(); +} diff --git a/src/Logger.h b/src/Logger.h new file mode 100644 index 0000000..e6d2fba --- /dev/null +++ b/src/Logger.h @@ -0,0 +1,341 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Logger_h +#define Logger_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ----------------------------------------------------------------------------- + +// values must be in sync with config +enum class LogLevel { + emergency = 0, + alert = 1, + critical = 2, + error = 3, + warning = 4, + notice = 5, + informational = 6, + debug = 7 +}; + +std::ostream &operator<<(std::ostream &os, const LogLevel &c); + +// ----------------------------------------------------------------------------- + +class LogRecord { +public: + LogRecord(LogLevel level, std::string message) + : _level(level) + , _message(std::move(message)) + , _time_point(std::chrono::system_clock::now()) {} + virtual ~LogRecord() = default; + + [[nodiscard]] LogLevel getLevel() const { return _level; } + void setLevel(LogLevel level) { _level = level; } + + [[nodiscard]] std::string getMessage() const { return _message; } + void setMessage(const std::string &message) { _message = message; } + + [[nodiscard]] std::chrono::system_clock::time_point getTimePoint() const { + return _time_point; + } + void setTimePoint(std::chrono::system_clock::time_point time_point) { + _time_point = time_point; + } + +private: + LogLevel _level; + std::string _message; + std::chrono::system_clock::time_point _time_point; +}; + +// ----------------------------------------------------------------------------- + +class Formatter { +public: + virtual ~Formatter() = default; + virtual void format(std::ostream &os, const LogRecord &record) = 0; +}; + +class SimpleFormatter : public Formatter { + friend class Handler; + void format(std::ostream &os, const LogRecord &record) override; +}; + +// ----------------------------------------------------------------------------- + +class Handler { +public: + virtual ~Handler() { setFormatter(std::unique_ptr()); } + virtual void publish(const LogRecord &record) = 0; + + [[nodiscard]] Formatter *getFormatter() const { return _formatter; } + void setFormatter(std::unique_ptr formatter) { + delete _formatter; + _formatter = formatter.release(); + } + +protected: + Handler() : _formatter(new SimpleFormatter()) {} + +private: + std::atomic _formatter; +}; + +class SharedStreamHandler : public Handler { +public: + SharedStreamHandler(std::mutex &mutex, std::ostream &os); + +private: + // The mutex protects the _os. + std::mutex &_mutex; + std::ostream &_os; + + void publish(const LogRecord &record) override; +}; + +class StreamHandler : public SharedStreamHandler { +public: + explicit StreamHandler(std::ostream &os); + +private: + // The mutex protects the output stream, see SharedStreamHandler. + std::mutex _mutex; +}; + +class FileHandler : public StreamHandler { +public: + explicit FileHandler(const std::string &filename); + +private: + std::ofstream _os; +}; + +// ----------------------------------------------------------------------------- + +class Logger { +public: + static Logger *getLogger(const std::string &name); + + virtual ~Logger() = default; + + [[nodiscard]] bool isLoggable(LogLevel level) const; + + [[nodiscard]] virtual std::string getName() const = 0; + + [[nodiscard]] virtual Logger *getParent() const = 0; + + [[nodiscard]] virtual LogLevel getLevel() const = 0; + virtual void setLevel(LogLevel level) = 0; + + [[nodiscard]] virtual Handler *getHandler() const = 0; + virtual void setHandler(std::unique_ptr handler) = 0; + + [[nodiscard]] virtual bool getUseParentHandlers() const = 0; + virtual void setUseParentHandlers(bool useParentHandlers) = 0; + + virtual void emitContext(std::ostream &os) const = 0; + + virtual void log(const LogRecord &record) = 0; +}; + +class ConcreteLogger : public Logger { +public: + ConcreteLogger(const std::string &name, Logger *parent); + ~ConcreteLogger() override; + + [[nodiscard]] std::string getName() const override; + + [[nodiscard]] Logger *getParent() const override; + + [[nodiscard]] LogLevel getLevel() const override; + void setLevel(LogLevel level) override; + + [[nodiscard]] Handler *getHandler() const override; + void setHandler(std::unique_ptr handler) override; + + [[nodiscard]] bool getUseParentHandlers() const override; + void setUseParentHandlers(bool useParentHandlers) override; + + void emitContext(std::ostream &os) const override; + + void log(const LogRecord &record) override; + +private: + const std::string _name; + Logger *const _parent; + std::atomic _level; + std::atomic _handler; + std::atomic _use_parent_handlers; +}; + +class LoggerDecorator : public Logger { +public: + explicit LoggerDecorator(Logger *logger); + + [[nodiscard]] std::string getName() const override; + + [[nodiscard]] Logger *getParent() const override; + + [[nodiscard]] LogLevel getLevel() const override; + void setLevel(LogLevel level) override; + + [[nodiscard]] Handler *getHandler() const override; + void setHandler(std::unique_ptr handler) override; + + [[nodiscard]] bool getUseParentHandlers() const override; + void setUseParentHandlers(bool useParentHandlers) override; + + void emitContext(std::ostream &os) const override; + + void log(const LogRecord &record) override; + +protected: + Logger *const _logger; +}; + +class ContextLogger : public LoggerDecorator { +public: + using ContextEmitter = std::function; + + ContextLogger(Logger *logger, ContextEmitter context) + : LoggerDecorator(logger), _context(std::move(context)) {} + + void emitContext(std::ostream &os) const override; + +private: + const ContextEmitter _context; +}; + +// ----------------------------------------------------------------------------- + +class LogManager { +public: + static LogManager *getLogManager() { return &_global_log_manager; } + Logger *getLogger(const std::string &name); + +private: + static LogManager _global_log_manager; + + // The mutex protects _known_loggers. + std::mutex _mutex; + std::unordered_map> _known_loggers; + + Logger *lookup(const std::string &name, Logger *parent); +}; + +// ----------------------------------------------------------------------------- + +class LogStream { +public: + LogStream(Logger *logger, LogLevel level) : _logger(logger), _level(level) { + // The test and all the similar ones below are just optimizations. + if (_logger->isLoggable(_level)) { + _logger->emitContext(_os); + } + } + + virtual ~LogStream() { + if (_logger->isLoggable(_level)) { + _logger->log(LogRecord(_level, _os.str())); + } + } + + template + std::ostream &operator<<(const T &t) { + return _logger->isLoggable(_level) ? (_os << t) : _os; + } + +protected: + Logger *const _logger; + const LogLevel _level; + std::ostringstream _os; +}; + +// ----------------------------------------------------------------------------- + +struct Emergency : public LogStream { + explicit Emergency(Logger *logger) + : LogStream(logger, LogLevel::emergency) {} +}; + +struct Alert : public LogStream { + explicit Alert(Logger *logger) : LogStream(logger, LogLevel::alert) {} +}; + +struct Critical : public LogStream { + explicit Critical(Logger *logger) : LogStream(logger, LogLevel::critical) {} +}; + +struct Error : public LogStream { + explicit Error(Logger *logger) : LogStream(logger, LogLevel::error) {} +}; + +struct Warning : public LogStream { + explicit Warning(Logger *logger) : LogStream(logger, LogLevel::warning) {} +}; + +struct Notice : public LogStream { + explicit Notice(Logger *logger) : LogStream(logger, LogLevel::notice) {} +}; + +struct Informational : public LogStream { + explicit Informational(Logger *logger) + : LogStream(logger, LogLevel::informational) {} +}; + +struct Debug : public LogStream { + explicit Debug(Logger *logger) : LogStream(logger, LogLevel::debug) {} +}; + +// ----------------------------------------------------------------------------- + +class generic_error : public std::system_error { +public: + generic_error() : std::system_error(errno, std::generic_category()) {} + + explicit generic_error(const char *what_arg) + : std::system_error(errno, std::generic_category(), what_arg) {} + + explicit generic_error(const std::string &what_arg) + : std::system_error(errno, std::generic_category(), what_arg) {} +}; + +std::ostream &operator<<(std::ostream &os, const generic_error &ge); + +#endif // Logger_h diff --git a/src/LogwatchListColumn.cc b/src/LogwatchListColumn.cc new file mode 100644 index 0000000..b3ab6b3 --- /dev/null +++ b/src/LogwatchListColumn.cc @@ -0,0 +1,84 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "LogwatchListColumn.h" +#include +#include +#include +#include "FileSystem.h" +#include "Logger.h" +#include "MonitoringCore.h" +#include "Row.h" +#include "pnp4nagios.h" + +#ifdef CMC +#include "Host.h" +#include "cmc.h" +#else +#include "nagios.h" +#endif + +std::vector LogwatchListColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + auto dir = getDirectory(row); + if (dir.empty()) { + return {}; + } + try { + if (fs::exists(dir)) { + std::vector filenames; + auto it = fs::directory_iterator(dir); + std::transform(begin(it), end(it), std::back_inserter(filenames), + [](const auto &entry) { + return entry.path().filename().string(); + }); + return filenames; + } + } catch (const fs::filesystem_error &e) { + Warning(logger()) << name() << ": " << e.what(); + } + return {}; +} + +std::string LogwatchListColumn::getDirectory(Row row) const { + auto logwatch_path = _mc->mkLogwatchPath(); + auto host_name = getHostName(row); + return logwatch_path.empty() || host_name.empty() + ? "" + : logwatch_path + pnp_cleanup(host_name); +} + +std::string LogwatchListColumn::getHostName(Row row) const { +#ifdef CMC + if (auto hst = columnData(row)) { + return hst->name(); + } +#else + if (auto hst = columnData(row)) { + return hst->name; + } +#endif + return ""; +} diff --git a/src/LogwatchListColumn.h b/src/LogwatchListColumn.h new file mode 100644 index 0000000..655ef52 --- /dev/null +++ b/src/LogwatchListColumn.h @@ -0,0 +1,57 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef LogwatchListColumn_h +#define LogwatchListColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class MonitoringCore; +class Row; + +class LogwatchListColumn : public ListColumn { +public: + LogwatchListColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, MonitoringCore *mc) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) {} + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *_mc; + + [[nodiscard]] std::string getDirectory(Row row) const; + [[nodiscard]] std::string getHostName(Row row) const; +}; + +#endif // LogwatchListColumn_h diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..fcb66a2 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,207 @@ +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + +CLANG_VERSION ?= 8 + +BEAR ?= bear +CPPCHECK ?= cppcheck +DOXYGEN ?= doxygen +IWYU_TOOL ?= iwyu_tool +RUN_CLANG_TIDY ?= \ + $(abs_top_srcdir)/scripts/run-clang-tidy.py \ + -clang-tidy-binary=clang-tidy-$(CLANG_VERSION) \ + -clang-apply-replacements-binary=clang-apply-replacements-$(CLANG_VERSION) + + +bin_PROGRAMS = unixcat + +unixcat_SOURCES = unixcat.cc +unixcat_LDADD = -lpthread +unixcat_LDFLAGS = -static-libstdc++ + +pkglib_LIBRARIES = liblivestatus.a + +liblivestatus_a_SOURCES = \ + AndingFilter.cc \ + AttributeListAsIntColumn.cc \ + AttributeListColumn.cc \ + BlobColumn.cc \ + ClientQueue.cc \ + Column.cc \ + ColumnFilter.cc \ + ColumnsColumn.cc \ + CommentColumn.cc \ + ContactGroupsColumn.cc \ + ContactGroupsMemberColumn.cc \ + CountAggregator.cc \ + CustomTimeperiodColumn.cc \ + CustomVarsDictColumn.cc \ + CustomVarsDictFilter.cc \ + CustomVarsExplicitColumn.cc \ + CustomVarsNamesColumn.cc \ + CustomVarsValuesColumn.cc \ + DoubleColumn.cc \ + DoubleFilter.cc \ + DowntimeColumn.cc \ + DowntimeOrComment.cc \ + DowntimesOrComments.cc \ + DynamicColumn.cc \ + DynamicEventConsoleReplicationColumn.cc \ + DynamicLogwatchFileColumn.cc \ + EventConsoleConnection.cc \ + Filter.cc \ + HostContactsColumn.cc \ + HostFileColumn.cc \ + HostGroupsColumn.cc \ + HostListColumn.cc \ + HostListStateColumn.cc \ + HostServiceState.cc \ + HostSpecialDoubleColumn.cc \ + HostSpecialIntColumn.cc \ + InputBuffer.cc \ + IntColumn.cc \ + IntFilter.cc \ + ListColumn.cc \ + ListFilter.cc \ + LogCache.cc \ + LogEntry.cc \ + Logfile.cc \ + Logger.cc \ + LogwatchListColumn.cc \ + MetricsColumn.cc \ + NullColumn.cc \ + OffsetBoolColumn.cc \ + OffsetDoubleColumn.cc \ + OffsetIntColumn.cc \ + OffsetPerfdataColumn.cc \ + OffsetSStringColumn.cc \ + OffsetStringColumn.cc \ + OffsetStringHostMacroColumn.cc \ + OffsetStringMacroColumn.cc \ + OffsetStringServiceMacroColumn.cc \ + OffsetTimeColumn.cc \ + OringFilter.cc \ + OutputBuffer.cc \ + PerfdataAggregator.cc \ + Query.cc \ + RegExp.cc \ + Renderer.cc \ + RendererBrokenCSV.cc \ + RendererCSV.cc \ + RendererJSON.cc \ + RendererPython.cc \ + RendererPython3.cc \ + ServiceContactsColumn.cc \ + ServiceGroupMembersColumn.cc \ + ServiceGroupsColumn.cc \ + ServiceListColumn.cc \ + ServiceListStateColumn.cc \ + ServiceSpecialDoubleColumn.cc \ + ServiceSpecialIntColumn.cc \ + StatsColumn.cc \ + StatusSpecialIntColumn.cc \ + Store.cc \ + StringColumn.cc \ + StringFilter.cc \ + StringUtils.cc \ + Table.cc \ + TableColumns.cc \ + TableCommands.cc \ + TableComments.cc \ + TableContactGroups.cc \ + TableContacts.cc \ + TableDowntimes.cc \ + TableEventConsole.cc \ + TableEventConsoleEvents.cc \ + TableEventConsoleHistory.cc \ + TableEventConsoleReplication.cc \ + TableEventConsoleRules.cc \ + TableEventConsoleStatus.cc \ + TableHostGroups.cc \ + TableHosts.cc \ + TableHostsByGroup.cc \ + TableLog.cc \ + TableServiceGroups.cc \ + TableServices.cc \ + TableServicesByGroup.cc \ + TableServicesByHostGroup.cc \ + TableStateHistory.cc \ + TableStatus.cc \ + TableTimeperiods.cc \ + TimeColumn.cc \ + TimeFilter.cc \ + TimeperiodColumn.cc \ + TimeperiodsCache.cc \ + Triggers.cc \ + auth.cc \ + global_counters.cc \ + mk_inventory.cc \ + mk_logwatch.cc \ + module.cc \ + opids.cc \ + pnp4nagios.cc \ + strutil.cc + +.PHONY: tidy iwyu cppcheck cppcheck-xml documentation + +liblivestatus_a_CPPFLAGS = -I.. @BOOST_CPPFLAGS@ @RE2_CPPFLAGS@ +liblivestatus_a_CXXFLAGS = -fPIC + +livestatus.o: $(liblivestatus_a_OBJECTS) +# Note: libstdc++fs is only available as a static library, so we are lucky. For +# RE2 we make sure that this is the case, too. + $(CXXLINK) -shared $^ -lstdc++fs -lpthread -static-libstdc++ @BOOST_LDFLAGS@ @BOOST_ASIO_LIB@ @RE2_LDFLAGS@ @RE2_LIBS@ +# To make sure we can dlopen() our NEB later + $(CXX) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c NagiosMockup.cc -o NagiosMockup.o + $(CXX) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) NagiosMockup.o $@ -o NagiosMockup + $(RM) NagiosMockup + +compile_commands.json: Makefile $(wildcard *.cc *.h) + $(MAKE) clean + $(BEAR) $(MAKE) -j4 + +tidy: compile_commands.json + $(RUN_CLANG_TIDY) -quiet -j6 + +iwyu: compile_commands.json + $(IWYU_TOOL) --output-format=clang -p . -- --mapping_file=$(abs_top_srcdir)/livestatus/iwyu-mappings/check_mk.imp + +cppcheck: compile_commands.json + $(CPPCHECK) -UCMC --enable=all --suppressions-list=$(abs_top_srcdir)/.cppcheck-suppressions --inline-suppr --project=compile_commands.json --quiet --template=gcc + +cppcheck-xml: compile_commands.json + $(CPPCHECK) -UCMC --enable=all --suppressions-list=$(abs_top_srcdir)/.cppcheck-suppressions --inline-suppr --project=compile_commands.json --quiet --template=gcc --xml --xml-version=2 2> cppcheck-result.xml + +documentation: + $(DOXYGEN) doc/Doxyfile + +all-local: livestatus.o + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + $(INSTALL_PROGRAM) livestatus.o $(DESTDIR)$(pkglibdir) + rm -f $(DESTDIR)$(pkglibdir)/liblivestatus.a + +clean-local: + rm -rf *~ compile_commands.json cppcheck-result.xml html diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..a49cf7b --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,2779 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 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@ + +# +------------------------------------------------------------------+ +# | ____ _ _ __ __ _ __ | +# | / ___| |__ ___ ___| | __ | \/ | |/ / | +# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +# | | |___| | | | __/ (__| < | | | | . \ | +# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +# | | +# | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +# +------------------------------------------------------------------+ +# +# This file is part of Check_MK. +# The official homepage is at http://mathias-kettner.de/check_mk. +# +# check_mk 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 in version 2. check_mk is distributed +# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more de- +# tails. You should have received a copy of the GNU General Public +# License along with GNU Make; see the file COPYING. If not, write +# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +# Boston, MA 02110-1301 USA. + + +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@ +bin_PROGRAMS = unixcat$(EXEEXT) +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_asio.m4 \ + $(top_srcdir)/m4/ax_boost_base.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/standalone/config_files.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)" "$(DESTDIR)$(bindir)" +LIBRARIES = $(pkglib_LIBRARIES) +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +liblivestatus_a_AR = $(AR) $(ARFLAGS) +liblivestatus_a_LIBADD = +am_liblivestatus_a_OBJECTS = liblivestatus_a-AndingFilter.$(OBJEXT) \ + liblivestatus_a-AttributeListAsIntColumn.$(OBJEXT) \ + liblivestatus_a-AttributeListColumn.$(OBJEXT) \ + liblivestatus_a-BlobColumn.$(OBJEXT) \ + liblivestatus_a-ClientQueue.$(OBJEXT) \ + liblivestatus_a-Column.$(OBJEXT) \ + liblivestatus_a-ColumnFilter.$(OBJEXT) \ + liblivestatus_a-ColumnsColumn.$(OBJEXT) \ + liblivestatus_a-CommentColumn.$(OBJEXT) \ + liblivestatus_a-ContactGroupsColumn.$(OBJEXT) \ + liblivestatus_a-ContactGroupsMemberColumn.$(OBJEXT) \ + liblivestatus_a-CountAggregator.$(OBJEXT) \ + liblivestatus_a-CustomTimeperiodColumn.$(OBJEXT) \ + liblivestatus_a-CustomVarsDictColumn.$(OBJEXT) \ + liblivestatus_a-CustomVarsDictFilter.$(OBJEXT) \ + liblivestatus_a-CustomVarsExplicitColumn.$(OBJEXT) \ + liblivestatus_a-CustomVarsNamesColumn.$(OBJEXT) \ + liblivestatus_a-CustomVarsValuesColumn.$(OBJEXT) \ + liblivestatus_a-DoubleColumn.$(OBJEXT) \ + liblivestatus_a-DoubleFilter.$(OBJEXT) \ + liblivestatus_a-DowntimeColumn.$(OBJEXT) \ + liblivestatus_a-DowntimeOrComment.$(OBJEXT) \ + liblivestatus_a-DowntimesOrComments.$(OBJEXT) \ + liblivestatus_a-DynamicColumn.$(OBJEXT) \ + liblivestatus_a-DynamicEventConsoleReplicationColumn.$(OBJEXT) \ + liblivestatus_a-DynamicLogwatchFileColumn.$(OBJEXT) \ + liblivestatus_a-EventConsoleConnection.$(OBJEXT) \ + liblivestatus_a-Filter.$(OBJEXT) \ + liblivestatus_a-HostContactsColumn.$(OBJEXT) \ + liblivestatus_a-HostFileColumn.$(OBJEXT) \ + liblivestatus_a-HostGroupsColumn.$(OBJEXT) \ + liblivestatus_a-HostListColumn.$(OBJEXT) \ + liblivestatus_a-HostListStateColumn.$(OBJEXT) \ + liblivestatus_a-HostServiceState.$(OBJEXT) \ + liblivestatus_a-HostSpecialDoubleColumn.$(OBJEXT) \ + liblivestatus_a-HostSpecialIntColumn.$(OBJEXT) \ + liblivestatus_a-InputBuffer.$(OBJEXT) \ + liblivestatus_a-IntColumn.$(OBJEXT) \ + liblivestatus_a-IntFilter.$(OBJEXT) \ + liblivestatus_a-ListColumn.$(OBJEXT) \ + liblivestatus_a-ListFilter.$(OBJEXT) \ + liblivestatus_a-LogCache.$(OBJEXT) \ + liblivestatus_a-LogEntry.$(OBJEXT) \ + liblivestatus_a-Logfile.$(OBJEXT) \ + liblivestatus_a-Logger.$(OBJEXT) \ + liblivestatus_a-LogwatchListColumn.$(OBJEXT) \ + liblivestatus_a-MetricsColumn.$(OBJEXT) \ + liblivestatus_a-NullColumn.$(OBJEXT) \ + liblivestatus_a-OffsetBoolColumn.$(OBJEXT) \ + liblivestatus_a-OffsetDoubleColumn.$(OBJEXT) \ + liblivestatus_a-OffsetIntColumn.$(OBJEXT) \ + liblivestatus_a-OffsetPerfdataColumn.$(OBJEXT) \ + liblivestatus_a-OffsetSStringColumn.$(OBJEXT) \ + liblivestatus_a-OffsetStringColumn.$(OBJEXT) \ + liblivestatus_a-OffsetStringHostMacroColumn.$(OBJEXT) \ + liblivestatus_a-OffsetStringMacroColumn.$(OBJEXT) \ + liblivestatus_a-OffsetStringServiceMacroColumn.$(OBJEXT) \ + liblivestatus_a-OffsetTimeColumn.$(OBJEXT) \ + liblivestatus_a-OringFilter.$(OBJEXT) \ + liblivestatus_a-OutputBuffer.$(OBJEXT) \ + liblivestatus_a-PerfdataAggregator.$(OBJEXT) \ + liblivestatus_a-Query.$(OBJEXT) \ + liblivestatus_a-RegExp.$(OBJEXT) \ + liblivestatus_a-Renderer.$(OBJEXT) \ + liblivestatus_a-RendererBrokenCSV.$(OBJEXT) \ + liblivestatus_a-RendererCSV.$(OBJEXT) \ + liblivestatus_a-RendererJSON.$(OBJEXT) \ + liblivestatus_a-RendererPython.$(OBJEXT) \ + liblivestatus_a-RendererPython3.$(OBJEXT) \ + liblivestatus_a-ServiceContactsColumn.$(OBJEXT) \ + liblivestatus_a-ServiceGroupMembersColumn.$(OBJEXT) \ + liblivestatus_a-ServiceGroupsColumn.$(OBJEXT) \ + liblivestatus_a-ServiceListColumn.$(OBJEXT) \ + liblivestatus_a-ServiceListStateColumn.$(OBJEXT) \ + liblivestatus_a-ServiceSpecialDoubleColumn.$(OBJEXT) \ + liblivestatus_a-ServiceSpecialIntColumn.$(OBJEXT) \ + liblivestatus_a-StatsColumn.$(OBJEXT) \ + liblivestatus_a-StatusSpecialIntColumn.$(OBJEXT) \ + liblivestatus_a-Store.$(OBJEXT) \ + liblivestatus_a-StringColumn.$(OBJEXT) \ + liblivestatus_a-StringFilter.$(OBJEXT) \ + liblivestatus_a-StringUtils.$(OBJEXT) \ + liblivestatus_a-Table.$(OBJEXT) \ + liblivestatus_a-TableColumns.$(OBJEXT) \ + liblivestatus_a-TableCommands.$(OBJEXT) \ + liblivestatus_a-TableComments.$(OBJEXT) \ + liblivestatus_a-TableContactGroups.$(OBJEXT) \ + liblivestatus_a-TableContacts.$(OBJEXT) \ + liblivestatus_a-TableDowntimes.$(OBJEXT) \ + liblivestatus_a-TableEventConsole.$(OBJEXT) \ + liblivestatus_a-TableEventConsoleEvents.$(OBJEXT) \ + liblivestatus_a-TableEventConsoleHistory.$(OBJEXT) \ + liblivestatus_a-TableEventConsoleReplication.$(OBJEXT) \ + liblivestatus_a-TableEventConsoleRules.$(OBJEXT) \ + liblivestatus_a-TableEventConsoleStatus.$(OBJEXT) \ + liblivestatus_a-TableHostGroups.$(OBJEXT) \ + liblivestatus_a-TableHosts.$(OBJEXT) \ + liblivestatus_a-TableHostsByGroup.$(OBJEXT) \ + liblivestatus_a-TableLog.$(OBJEXT) \ + liblivestatus_a-TableServiceGroups.$(OBJEXT) \ + liblivestatus_a-TableServices.$(OBJEXT) \ + liblivestatus_a-TableServicesByGroup.$(OBJEXT) \ + liblivestatus_a-TableServicesByHostGroup.$(OBJEXT) \ + liblivestatus_a-TableStateHistory.$(OBJEXT) \ + liblivestatus_a-TableStatus.$(OBJEXT) \ + liblivestatus_a-TableTimeperiods.$(OBJEXT) \ + liblivestatus_a-TimeColumn.$(OBJEXT) \ + liblivestatus_a-TimeFilter.$(OBJEXT) \ + liblivestatus_a-TimeperiodColumn.$(OBJEXT) \ + liblivestatus_a-TimeperiodsCache.$(OBJEXT) \ + liblivestatus_a-Triggers.$(OBJEXT) \ + liblivestatus_a-auth.$(OBJEXT) \ + liblivestatus_a-global_counters.$(OBJEXT) \ + liblivestatus_a-mk_inventory.$(OBJEXT) \ + liblivestatus_a-mk_logwatch.$(OBJEXT) \ + liblivestatus_a-module.$(OBJEXT) \ + liblivestatus_a-opids.$(OBJEXT) \ + liblivestatus_a-pnp4nagios.$(OBJEXT) \ + liblivestatus_a-strutil.$(OBJEXT) +liblivestatus_a_OBJECTS = $(am_liblivestatus_a_OBJECTS) +PROGRAMS = $(bin_PROGRAMS) +am_unixcat_OBJECTS = unixcat.$(OBJEXT) +unixcat_OBJECTS = $(am_unixcat_OBJECTS) +unixcat_DEPENDENCIES = +unixcat_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(unixcat_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__depfiles_maybe = depfiles +am__mv = mv -f +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 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(liblivestatus_a_SOURCES) $(unixcat_SOURCES) +DIST_SOURCES = $(liblivestatus_a_SOURCES) $(unixcat_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@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BOOST_ASIO_LIB = @BOOST_ASIO_LIB@ +BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ +BOOST_LDFLAGS = @BOOST_LDFLAGS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +HAVE_CXX17 = @HAVE_CXX17@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +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@ +RANLIB = @RANLIB@ +RE2_CPPFLAGS = @RE2_CPPFLAGS@ +RE2_LDFLAGS = @RE2_LDFLAGS@ +RE2_LIBS = @RE2_LIBS@ +RRDLIB = @RRDLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +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_CXX = @ac_ct_CXX@ +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@ +nagios_headers = @nagios_headers@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +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@ +unixcat_SOURCES = unixcat.cc +unixcat_LDADD = -lpthread +unixcat_LDFLAGS = -static-libstdc++ +pkglib_LIBRARIES = liblivestatus.a +liblivestatus_a_SOURCES = \ + AndingFilter.cc \ + AttributeListAsIntColumn.cc \ + AttributeListColumn.cc \ + BlobColumn.cc \ + ClientQueue.cc \ + Column.cc \ + ColumnFilter.cc \ + ColumnsColumn.cc \ + CommentColumn.cc \ + ContactGroupsColumn.cc \ + ContactGroupsMemberColumn.cc \ + CountAggregator.cc \ + CustomTimeperiodColumn.cc \ + CustomVarsDictColumn.cc \ + CustomVarsDictFilter.cc \ + CustomVarsExplicitColumn.cc \ + CustomVarsNamesColumn.cc \ + CustomVarsValuesColumn.cc \ + DoubleColumn.cc \ + DoubleFilter.cc \ + DowntimeColumn.cc \ + DowntimeOrComment.cc \ + DowntimesOrComments.cc \ + DynamicColumn.cc \ + DynamicEventConsoleReplicationColumn.cc \ + DynamicLogwatchFileColumn.cc \ + EventConsoleConnection.cc \ + Filter.cc \ + HostContactsColumn.cc \ + HostFileColumn.cc \ + HostGroupsColumn.cc \ + HostListColumn.cc \ + HostListStateColumn.cc \ + HostServiceState.cc \ + HostSpecialDoubleColumn.cc \ + HostSpecialIntColumn.cc \ + InputBuffer.cc \ + IntColumn.cc \ + IntFilter.cc \ + ListColumn.cc \ + ListFilter.cc \ + LogCache.cc \ + LogEntry.cc \ + Logfile.cc \ + Logger.cc \ + LogwatchListColumn.cc \ + MetricsColumn.cc \ + NullColumn.cc \ + OffsetBoolColumn.cc \ + OffsetDoubleColumn.cc \ + OffsetIntColumn.cc \ + OffsetPerfdataColumn.cc \ + OffsetSStringColumn.cc \ + OffsetStringColumn.cc \ + OffsetStringHostMacroColumn.cc \ + OffsetStringMacroColumn.cc \ + OffsetStringServiceMacroColumn.cc \ + OffsetTimeColumn.cc \ + OringFilter.cc \ + OutputBuffer.cc \ + PerfdataAggregator.cc \ + Query.cc \ + RegExp.cc \ + Renderer.cc \ + RendererBrokenCSV.cc \ + RendererCSV.cc \ + RendererJSON.cc \ + RendererPython.cc \ + RendererPython3.cc \ + ServiceContactsColumn.cc \ + ServiceGroupMembersColumn.cc \ + ServiceGroupsColumn.cc \ + ServiceListColumn.cc \ + ServiceListStateColumn.cc \ + ServiceSpecialDoubleColumn.cc \ + ServiceSpecialIntColumn.cc \ + StatsColumn.cc \ + StatusSpecialIntColumn.cc \ + Store.cc \ + StringColumn.cc \ + StringFilter.cc \ + StringUtils.cc \ + Table.cc \ + TableColumns.cc \ + TableCommands.cc \ + TableComments.cc \ + TableContactGroups.cc \ + TableContacts.cc \ + TableDowntimes.cc \ + TableEventConsole.cc \ + TableEventConsoleEvents.cc \ + TableEventConsoleHistory.cc \ + TableEventConsoleReplication.cc \ + TableEventConsoleRules.cc \ + TableEventConsoleStatus.cc \ + TableHostGroups.cc \ + TableHosts.cc \ + TableHostsByGroup.cc \ + TableLog.cc \ + TableServiceGroups.cc \ + TableServices.cc \ + TableServicesByGroup.cc \ + TableServicesByHostGroup.cc \ + TableStateHistory.cc \ + TableStatus.cc \ + TableTimeperiods.cc \ + TimeColumn.cc \ + TimeFilter.cc \ + TimeperiodColumn.cc \ + TimeperiodsCache.cc \ + Triggers.cc \ + auth.cc \ + global_counters.cc \ + mk_inventory.cc \ + mk_logwatch.cc \ + module.cc \ + opids.cc \ + pnp4nagios.cc \ + strutil.cc + +liblivestatus_a_CPPFLAGS = -I.. @BOOST_CPPFLAGS@ @RE2_CPPFLAGS@ +liblivestatus_a_CXXFLAGS = -fPIC +all: all-am + +.SUFFIXES: +.SUFFIXES: .cc .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) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/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__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + 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-pkglibLIBRARIES: $(pkglib_LIBRARIES) + @$(NORMAL_INSTALL) + @list='$(pkglib_LIBRARIES)'; 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 " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(pkglibdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(pkglib_LIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(pkglibdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(pkglibdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-pkglibLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LIBRARIES)'; test -n "$(pkglibdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkglibdir)'; $(am__uninstall_files_from_dir) + +clean-pkglibLIBRARIES: + -test -z "$(pkglib_LIBRARIES)" || rm -f $(pkglib_LIBRARIES) + +liblivestatus.a: $(liblivestatus_a_OBJECTS) $(liblivestatus_a_DEPENDENCIES) $(EXTRA_liblivestatus_a_DEPENDENCIES) + $(AM_V_at)-rm -f liblivestatus.a + $(AM_V_AR)$(liblivestatus_a_AR) liblivestatus.a $(liblivestatus_a_OBJECTS) $(liblivestatus_a_LIBADD) + $(AM_V_at)$(RANLIB) liblivestatus.a +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +unixcat$(EXEEXT): $(unixcat_OBJECTS) $(unixcat_DEPENDENCIES) $(EXTRA_unixcat_DEPENDENCIES) + @rm -f unixcat$(EXEEXT) + $(AM_V_CXXLD)$(unixcat_LINK) $(unixcat_OBJECTS) $(unixcat_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-AndingFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-AttributeListAsIntColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-AttributeListColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-BlobColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ClientQueue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Column.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ColumnFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ColumnsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CommentColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ContactGroupsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ContactGroupsMemberColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CountAggregator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CustomTimeperiodColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CustomVarsDictColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CustomVarsDictFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CustomVarsExplicitColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CustomVarsNamesColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-CustomVarsValuesColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DoubleColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DoubleFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DowntimeColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DowntimeOrComment.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DowntimesOrComments.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DynamicColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DynamicEventConsoleReplicationColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-DynamicLogwatchFileColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-EventConsoleConnection.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Filter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostContactsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostFileColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostGroupsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostListColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostListStateColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostServiceState.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostSpecialDoubleColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-HostSpecialIntColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-InputBuffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-IntColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-IntFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ListColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ListFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-LogCache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-LogEntry.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Logfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Logger.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-LogwatchListColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-MetricsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-NullColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetBoolColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetDoubleColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetIntColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetPerfdataColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetSStringColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetStringColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetStringHostMacroColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetStringMacroColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetStringServiceMacroColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OffsetTimeColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OringFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-OutputBuffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-PerfdataAggregator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Query.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-RegExp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Renderer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-RendererBrokenCSV.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-RendererCSV.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-RendererJSON.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-RendererPython.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-RendererPython3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ServiceContactsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ServiceGroupMembersColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ServiceGroupsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ServiceListColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ServiceListStateColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ServiceSpecialDoubleColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-ServiceSpecialIntColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-StatsColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-StatusSpecialIntColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Store.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-StringColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-StringFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-StringUtils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Table.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableColumns.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableCommands.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableComments.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableContactGroups.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableContacts.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableDowntimes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableEventConsole.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableEventConsoleEvents.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableEventConsoleHistory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableEventConsoleReplication.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableEventConsoleRules.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableEventConsoleStatus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableHostGroups.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableHosts.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableHostsByGroup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableLog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableServiceGroups.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableServices.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableServicesByGroup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableServicesByHostGroup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableStateHistory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableStatus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TableTimeperiods.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TimeColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TimeFilter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TimeperiodColumn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-TimeperiodsCache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-Triggers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-auth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-global_counters.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-mk_inventory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-mk_logwatch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-module.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-opids.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-pnp4nagios.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liblivestatus_a-strutil.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unixcat.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +liblivestatus_a-AndingFilter.o: AndingFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-AndingFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-AndingFilter.Tpo -c -o liblivestatus_a-AndingFilter.o `test -f 'AndingFilter.cc' || echo '$(srcdir)/'`AndingFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-AndingFilter.Tpo $(DEPDIR)/liblivestatus_a-AndingFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AndingFilter.cc' object='liblivestatus_a-AndingFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-AndingFilter.o `test -f 'AndingFilter.cc' || echo '$(srcdir)/'`AndingFilter.cc + +liblivestatus_a-AndingFilter.obj: AndingFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-AndingFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-AndingFilter.Tpo -c -o liblivestatus_a-AndingFilter.obj `if test -f 'AndingFilter.cc'; then $(CYGPATH_W) 'AndingFilter.cc'; else $(CYGPATH_W) '$(srcdir)/AndingFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-AndingFilter.Tpo $(DEPDIR)/liblivestatus_a-AndingFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AndingFilter.cc' object='liblivestatus_a-AndingFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-AndingFilter.obj `if test -f 'AndingFilter.cc'; then $(CYGPATH_W) 'AndingFilter.cc'; else $(CYGPATH_W) '$(srcdir)/AndingFilter.cc'; fi` + +liblivestatus_a-AttributeListAsIntColumn.o: AttributeListAsIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-AttributeListAsIntColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-AttributeListAsIntColumn.Tpo -c -o liblivestatus_a-AttributeListAsIntColumn.o `test -f 'AttributeListAsIntColumn.cc' || echo '$(srcdir)/'`AttributeListAsIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-AttributeListAsIntColumn.Tpo $(DEPDIR)/liblivestatus_a-AttributeListAsIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AttributeListAsIntColumn.cc' object='liblivestatus_a-AttributeListAsIntColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-AttributeListAsIntColumn.o `test -f 'AttributeListAsIntColumn.cc' || echo '$(srcdir)/'`AttributeListAsIntColumn.cc + +liblivestatus_a-AttributeListAsIntColumn.obj: AttributeListAsIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-AttributeListAsIntColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-AttributeListAsIntColumn.Tpo -c -o liblivestatus_a-AttributeListAsIntColumn.obj `if test -f 'AttributeListAsIntColumn.cc'; then $(CYGPATH_W) 'AttributeListAsIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/AttributeListAsIntColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-AttributeListAsIntColumn.Tpo $(DEPDIR)/liblivestatus_a-AttributeListAsIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AttributeListAsIntColumn.cc' object='liblivestatus_a-AttributeListAsIntColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-AttributeListAsIntColumn.obj `if test -f 'AttributeListAsIntColumn.cc'; then $(CYGPATH_W) 'AttributeListAsIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/AttributeListAsIntColumn.cc'; fi` + +liblivestatus_a-AttributeListColumn.o: AttributeListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-AttributeListColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-AttributeListColumn.Tpo -c -o liblivestatus_a-AttributeListColumn.o `test -f 'AttributeListColumn.cc' || echo '$(srcdir)/'`AttributeListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-AttributeListColumn.Tpo $(DEPDIR)/liblivestatus_a-AttributeListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AttributeListColumn.cc' object='liblivestatus_a-AttributeListColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-AttributeListColumn.o `test -f 'AttributeListColumn.cc' || echo '$(srcdir)/'`AttributeListColumn.cc + +liblivestatus_a-AttributeListColumn.obj: AttributeListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-AttributeListColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-AttributeListColumn.Tpo -c -o liblivestatus_a-AttributeListColumn.obj `if test -f 'AttributeListColumn.cc'; then $(CYGPATH_W) 'AttributeListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/AttributeListColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-AttributeListColumn.Tpo $(DEPDIR)/liblivestatus_a-AttributeListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='AttributeListColumn.cc' object='liblivestatus_a-AttributeListColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-AttributeListColumn.obj `if test -f 'AttributeListColumn.cc'; then $(CYGPATH_W) 'AttributeListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/AttributeListColumn.cc'; fi` + +liblivestatus_a-BlobColumn.o: BlobColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-BlobColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-BlobColumn.Tpo -c -o liblivestatus_a-BlobColumn.o `test -f 'BlobColumn.cc' || echo '$(srcdir)/'`BlobColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-BlobColumn.Tpo $(DEPDIR)/liblivestatus_a-BlobColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='BlobColumn.cc' object='liblivestatus_a-BlobColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-BlobColumn.o `test -f 'BlobColumn.cc' || echo '$(srcdir)/'`BlobColumn.cc + +liblivestatus_a-BlobColumn.obj: BlobColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-BlobColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-BlobColumn.Tpo -c -o liblivestatus_a-BlobColumn.obj `if test -f 'BlobColumn.cc'; then $(CYGPATH_W) 'BlobColumn.cc'; else $(CYGPATH_W) '$(srcdir)/BlobColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-BlobColumn.Tpo $(DEPDIR)/liblivestatus_a-BlobColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='BlobColumn.cc' object='liblivestatus_a-BlobColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-BlobColumn.obj `if test -f 'BlobColumn.cc'; then $(CYGPATH_W) 'BlobColumn.cc'; else $(CYGPATH_W) '$(srcdir)/BlobColumn.cc'; fi` + +liblivestatus_a-ClientQueue.o: ClientQueue.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ClientQueue.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ClientQueue.Tpo -c -o liblivestatus_a-ClientQueue.o `test -f 'ClientQueue.cc' || echo '$(srcdir)/'`ClientQueue.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ClientQueue.Tpo $(DEPDIR)/liblivestatus_a-ClientQueue.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientQueue.cc' object='liblivestatus_a-ClientQueue.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ClientQueue.o `test -f 'ClientQueue.cc' || echo '$(srcdir)/'`ClientQueue.cc + +liblivestatus_a-ClientQueue.obj: ClientQueue.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ClientQueue.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ClientQueue.Tpo -c -o liblivestatus_a-ClientQueue.obj `if test -f 'ClientQueue.cc'; then $(CYGPATH_W) 'ClientQueue.cc'; else $(CYGPATH_W) '$(srcdir)/ClientQueue.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ClientQueue.Tpo $(DEPDIR)/liblivestatus_a-ClientQueue.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ClientQueue.cc' object='liblivestatus_a-ClientQueue.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ClientQueue.obj `if test -f 'ClientQueue.cc'; then $(CYGPATH_W) 'ClientQueue.cc'; else $(CYGPATH_W) '$(srcdir)/ClientQueue.cc'; fi` + +liblivestatus_a-Column.o: Column.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Column.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Column.Tpo -c -o liblivestatus_a-Column.o `test -f 'Column.cc' || echo '$(srcdir)/'`Column.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Column.Tpo $(DEPDIR)/liblivestatus_a-Column.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Column.cc' object='liblivestatus_a-Column.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Column.o `test -f 'Column.cc' || echo '$(srcdir)/'`Column.cc + +liblivestatus_a-Column.obj: Column.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Column.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Column.Tpo -c -o liblivestatus_a-Column.obj `if test -f 'Column.cc'; then $(CYGPATH_W) 'Column.cc'; else $(CYGPATH_W) '$(srcdir)/Column.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Column.Tpo $(DEPDIR)/liblivestatus_a-Column.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Column.cc' object='liblivestatus_a-Column.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Column.obj `if test -f 'Column.cc'; then $(CYGPATH_W) 'Column.cc'; else $(CYGPATH_W) '$(srcdir)/Column.cc'; fi` + +liblivestatus_a-ColumnFilter.o: ColumnFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ColumnFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ColumnFilter.Tpo -c -o liblivestatus_a-ColumnFilter.o `test -f 'ColumnFilter.cc' || echo '$(srcdir)/'`ColumnFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ColumnFilter.Tpo $(DEPDIR)/liblivestatus_a-ColumnFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ColumnFilter.cc' object='liblivestatus_a-ColumnFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ColumnFilter.o `test -f 'ColumnFilter.cc' || echo '$(srcdir)/'`ColumnFilter.cc + +liblivestatus_a-ColumnFilter.obj: ColumnFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ColumnFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ColumnFilter.Tpo -c -o liblivestatus_a-ColumnFilter.obj `if test -f 'ColumnFilter.cc'; then $(CYGPATH_W) 'ColumnFilter.cc'; else $(CYGPATH_W) '$(srcdir)/ColumnFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ColumnFilter.Tpo $(DEPDIR)/liblivestatus_a-ColumnFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ColumnFilter.cc' object='liblivestatus_a-ColumnFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ColumnFilter.obj `if test -f 'ColumnFilter.cc'; then $(CYGPATH_W) 'ColumnFilter.cc'; else $(CYGPATH_W) '$(srcdir)/ColumnFilter.cc'; fi` + +liblivestatus_a-ColumnsColumn.o: ColumnsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ColumnsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ColumnsColumn.Tpo -c -o liblivestatus_a-ColumnsColumn.o `test -f 'ColumnsColumn.cc' || echo '$(srcdir)/'`ColumnsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ColumnsColumn.Tpo $(DEPDIR)/liblivestatus_a-ColumnsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ColumnsColumn.cc' object='liblivestatus_a-ColumnsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ColumnsColumn.o `test -f 'ColumnsColumn.cc' || echo '$(srcdir)/'`ColumnsColumn.cc + +liblivestatus_a-ColumnsColumn.obj: ColumnsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ColumnsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ColumnsColumn.Tpo -c -o liblivestatus_a-ColumnsColumn.obj `if test -f 'ColumnsColumn.cc'; then $(CYGPATH_W) 'ColumnsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ColumnsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ColumnsColumn.Tpo $(DEPDIR)/liblivestatus_a-ColumnsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ColumnsColumn.cc' object='liblivestatus_a-ColumnsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ColumnsColumn.obj `if test -f 'ColumnsColumn.cc'; then $(CYGPATH_W) 'ColumnsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ColumnsColumn.cc'; fi` + +liblivestatus_a-CommentColumn.o: CommentColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CommentColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CommentColumn.Tpo -c -o liblivestatus_a-CommentColumn.o `test -f 'CommentColumn.cc' || echo '$(srcdir)/'`CommentColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CommentColumn.Tpo $(DEPDIR)/liblivestatus_a-CommentColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CommentColumn.cc' object='liblivestatus_a-CommentColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CommentColumn.o `test -f 'CommentColumn.cc' || echo '$(srcdir)/'`CommentColumn.cc + +liblivestatus_a-CommentColumn.obj: CommentColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CommentColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CommentColumn.Tpo -c -o liblivestatus_a-CommentColumn.obj `if test -f 'CommentColumn.cc'; then $(CYGPATH_W) 'CommentColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CommentColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CommentColumn.Tpo $(DEPDIR)/liblivestatus_a-CommentColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CommentColumn.cc' object='liblivestatus_a-CommentColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CommentColumn.obj `if test -f 'CommentColumn.cc'; then $(CYGPATH_W) 'CommentColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CommentColumn.cc'; fi` + +liblivestatus_a-ContactGroupsColumn.o: ContactGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ContactGroupsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ContactGroupsColumn.Tpo -c -o liblivestatus_a-ContactGroupsColumn.o `test -f 'ContactGroupsColumn.cc' || echo '$(srcdir)/'`ContactGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ContactGroupsColumn.Tpo $(DEPDIR)/liblivestatus_a-ContactGroupsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ContactGroupsColumn.cc' object='liblivestatus_a-ContactGroupsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ContactGroupsColumn.o `test -f 'ContactGroupsColumn.cc' || echo '$(srcdir)/'`ContactGroupsColumn.cc + +liblivestatus_a-ContactGroupsColumn.obj: ContactGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ContactGroupsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ContactGroupsColumn.Tpo -c -o liblivestatus_a-ContactGroupsColumn.obj `if test -f 'ContactGroupsColumn.cc'; then $(CYGPATH_W) 'ContactGroupsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ContactGroupsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ContactGroupsColumn.Tpo $(DEPDIR)/liblivestatus_a-ContactGroupsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ContactGroupsColumn.cc' object='liblivestatus_a-ContactGroupsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ContactGroupsColumn.obj `if test -f 'ContactGroupsColumn.cc'; then $(CYGPATH_W) 'ContactGroupsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ContactGroupsColumn.cc'; fi` + +liblivestatus_a-ContactGroupsMemberColumn.o: ContactGroupsMemberColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ContactGroupsMemberColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ContactGroupsMemberColumn.Tpo -c -o liblivestatus_a-ContactGroupsMemberColumn.o `test -f 'ContactGroupsMemberColumn.cc' || echo '$(srcdir)/'`ContactGroupsMemberColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ContactGroupsMemberColumn.Tpo $(DEPDIR)/liblivestatus_a-ContactGroupsMemberColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ContactGroupsMemberColumn.cc' object='liblivestatus_a-ContactGroupsMemberColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ContactGroupsMemberColumn.o `test -f 'ContactGroupsMemberColumn.cc' || echo '$(srcdir)/'`ContactGroupsMemberColumn.cc + +liblivestatus_a-ContactGroupsMemberColumn.obj: ContactGroupsMemberColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ContactGroupsMemberColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ContactGroupsMemberColumn.Tpo -c -o liblivestatus_a-ContactGroupsMemberColumn.obj `if test -f 'ContactGroupsMemberColumn.cc'; then $(CYGPATH_W) 'ContactGroupsMemberColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ContactGroupsMemberColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ContactGroupsMemberColumn.Tpo $(DEPDIR)/liblivestatus_a-ContactGroupsMemberColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ContactGroupsMemberColumn.cc' object='liblivestatus_a-ContactGroupsMemberColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ContactGroupsMemberColumn.obj `if test -f 'ContactGroupsMemberColumn.cc'; then $(CYGPATH_W) 'ContactGroupsMemberColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ContactGroupsMemberColumn.cc'; fi` + +liblivestatus_a-CountAggregator.o: CountAggregator.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CountAggregator.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CountAggregator.Tpo -c -o liblivestatus_a-CountAggregator.o `test -f 'CountAggregator.cc' || echo '$(srcdir)/'`CountAggregator.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CountAggregator.Tpo $(DEPDIR)/liblivestatus_a-CountAggregator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CountAggregator.cc' object='liblivestatus_a-CountAggregator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CountAggregator.o `test -f 'CountAggregator.cc' || echo '$(srcdir)/'`CountAggregator.cc + +liblivestatus_a-CountAggregator.obj: CountAggregator.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CountAggregator.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CountAggregator.Tpo -c -o liblivestatus_a-CountAggregator.obj `if test -f 'CountAggregator.cc'; then $(CYGPATH_W) 'CountAggregator.cc'; else $(CYGPATH_W) '$(srcdir)/CountAggregator.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CountAggregator.Tpo $(DEPDIR)/liblivestatus_a-CountAggregator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CountAggregator.cc' object='liblivestatus_a-CountAggregator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CountAggregator.obj `if test -f 'CountAggregator.cc'; then $(CYGPATH_W) 'CountAggregator.cc'; else $(CYGPATH_W) '$(srcdir)/CountAggregator.cc'; fi` + +liblivestatus_a-CustomTimeperiodColumn.o: CustomTimeperiodColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomTimeperiodColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomTimeperiodColumn.Tpo -c -o liblivestatus_a-CustomTimeperiodColumn.o `test -f 'CustomTimeperiodColumn.cc' || echo '$(srcdir)/'`CustomTimeperiodColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomTimeperiodColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomTimeperiodColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomTimeperiodColumn.cc' object='liblivestatus_a-CustomTimeperiodColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomTimeperiodColumn.o `test -f 'CustomTimeperiodColumn.cc' || echo '$(srcdir)/'`CustomTimeperiodColumn.cc + +liblivestatus_a-CustomTimeperiodColumn.obj: CustomTimeperiodColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomTimeperiodColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomTimeperiodColumn.Tpo -c -o liblivestatus_a-CustomTimeperiodColumn.obj `if test -f 'CustomTimeperiodColumn.cc'; then $(CYGPATH_W) 'CustomTimeperiodColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomTimeperiodColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomTimeperiodColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomTimeperiodColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomTimeperiodColumn.cc' object='liblivestatus_a-CustomTimeperiodColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomTimeperiodColumn.obj `if test -f 'CustomTimeperiodColumn.cc'; then $(CYGPATH_W) 'CustomTimeperiodColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomTimeperiodColumn.cc'; fi` + +liblivestatus_a-CustomVarsDictColumn.o: CustomVarsDictColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsDictColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsDictColumn.Tpo -c -o liblivestatus_a-CustomVarsDictColumn.o `test -f 'CustomVarsDictColumn.cc' || echo '$(srcdir)/'`CustomVarsDictColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsDictColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsDictColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsDictColumn.cc' object='liblivestatus_a-CustomVarsDictColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsDictColumn.o `test -f 'CustomVarsDictColumn.cc' || echo '$(srcdir)/'`CustomVarsDictColumn.cc + +liblivestatus_a-CustomVarsDictColumn.obj: CustomVarsDictColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsDictColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsDictColumn.Tpo -c -o liblivestatus_a-CustomVarsDictColumn.obj `if test -f 'CustomVarsDictColumn.cc'; then $(CYGPATH_W) 'CustomVarsDictColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsDictColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsDictColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsDictColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsDictColumn.cc' object='liblivestatus_a-CustomVarsDictColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsDictColumn.obj `if test -f 'CustomVarsDictColumn.cc'; then $(CYGPATH_W) 'CustomVarsDictColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsDictColumn.cc'; fi` + +liblivestatus_a-CustomVarsDictFilter.o: CustomVarsDictFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsDictFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsDictFilter.Tpo -c -o liblivestatus_a-CustomVarsDictFilter.o `test -f 'CustomVarsDictFilter.cc' || echo '$(srcdir)/'`CustomVarsDictFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsDictFilter.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsDictFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsDictFilter.cc' object='liblivestatus_a-CustomVarsDictFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsDictFilter.o `test -f 'CustomVarsDictFilter.cc' || echo '$(srcdir)/'`CustomVarsDictFilter.cc + +liblivestatus_a-CustomVarsDictFilter.obj: CustomVarsDictFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsDictFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsDictFilter.Tpo -c -o liblivestatus_a-CustomVarsDictFilter.obj `if test -f 'CustomVarsDictFilter.cc'; then $(CYGPATH_W) 'CustomVarsDictFilter.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsDictFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsDictFilter.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsDictFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsDictFilter.cc' object='liblivestatus_a-CustomVarsDictFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsDictFilter.obj `if test -f 'CustomVarsDictFilter.cc'; then $(CYGPATH_W) 'CustomVarsDictFilter.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsDictFilter.cc'; fi` + +liblivestatus_a-CustomVarsExplicitColumn.o: CustomVarsExplicitColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsExplicitColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsExplicitColumn.Tpo -c -o liblivestatus_a-CustomVarsExplicitColumn.o `test -f 'CustomVarsExplicitColumn.cc' || echo '$(srcdir)/'`CustomVarsExplicitColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsExplicitColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsExplicitColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsExplicitColumn.cc' object='liblivestatus_a-CustomVarsExplicitColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsExplicitColumn.o `test -f 'CustomVarsExplicitColumn.cc' || echo '$(srcdir)/'`CustomVarsExplicitColumn.cc + +liblivestatus_a-CustomVarsExplicitColumn.obj: CustomVarsExplicitColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsExplicitColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsExplicitColumn.Tpo -c -o liblivestatus_a-CustomVarsExplicitColumn.obj `if test -f 'CustomVarsExplicitColumn.cc'; then $(CYGPATH_W) 'CustomVarsExplicitColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsExplicitColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsExplicitColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsExplicitColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsExplicitColumn.cc' object='liblivestatus_a-CustomVarsExplicitColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsExplicitColumn.obj `if test -f 'CustomVarsExplicitColumn.cc'; then $(CYGPATH_W) 'CustomVarsExplicitColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsExplicitColumn.cc'; fi` + +liblivestatus_a-CustomVarsNamesColumn.o: CustomVarsNamesColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsNamesColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsNamesColumn.Tpo -c -o liblivestatus_a-CustomVarsNamesColumn.o `test -f 'CustomVarsNamesColumn.cc' || echo '$(srcdir)/'`CustomVarsNamesColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsNamesColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsNamesColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsNamesColumn.cc' object='liblivestatus_a-CustomVarsNamesColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsNamesColumn.o `test -f 'CustomVarsNamesColumn.cc' || echo '$(srcdir)/'`CustomVarsNamesColumn.cc + +liblivestatus_a-CustomVarsNamesColumn.obj: CustomVarsNamesColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsNamesColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsNamesColumn.Tpo -c -o liblivestatus_a-CustomVarsNamesColumn.obj `if test -f 'CustomVarsNamesColumn.cc'; then $(CYGPATH_W) 'CustomVarsNamesColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsNamesColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsNamesColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsNamesColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsNamesColumn.cc' object='liblivestatus_a-CustomVarsNamesColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsNamesColumn.obj `if test -f 'CustomVarsNamesColumn.cc'; then $(CYGPATH_W) 'CustomVarsNamesColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsNamesColumn.cc'; fi` + +liblivestatus_a-CustomVarsValuesColumn.o: CustomVarsValuesColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsValuesColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsValuesColumn.Tpo -c -o liblivestatus_a-CustomVarsValuesColumn.o `test -f 'CustomVarsValuesColumn.cc' || echo '$(srcdir)/'`CustomVarsValuesColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsValuesColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsValuesColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsValuesColumn.cc' object='liblivestatus_a-CustomVarsValuesColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsValuesColumn.o `test -f 'CustomVarsValuesColumn.cc' || echo '$(srcdir)/'`CustomVarsValuesColumn.cc + +liblivestatus_a-CustomVarsValuesColumn.obj: CustomVarsValuesColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-CustomVarsValuesColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-CustomVarsValuesColumn.Tpo -c -o liblivestatus_a-CustomVarsValuesColumn.obj `if test -f 'CustomVarsValuesColumn.cc'; then $(CYGPATH_W) 'CustomVarsValuesColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsValuesColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-CustomVarsValuesColumn.Tpo $(DEPDIR)/liblivestatus_a-CustomVarsValuesColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CustomVarsValuesColumn.cc' object='liblivestatus_a-CustomVarsValuesColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-CustomVarsValuesColumn.obj `if test -f 'CustomVarsValuesColumn.cc'; then $(CYGPATH_W) 'CustomVarsValuesColumn.cc'; else $(CYGPATH_W) '$(srcdir)/CustomVarsValuesColumn.cc'; fi` + +liblivestatus_a-DoubleColumn.o: DoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DoubleColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DoubleColumn.Tpo -c -o liblivestatus_a-DoubleColumn.o `test -f 'DoubleColumn.cc' || echo '$(srcdir)/'`DoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-DoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DoubleColumn.cc' object='liblivestatus_a-DoubleColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DoubleColumn.o `test -f 'DoubleColumn.cc' || echo '$(srcdir)/'`DoubleColumn.cc + +liblivestatus_a-DoubleColumn.obj: DoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DoubleColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DoubleColumn.Tpo -c -o liblivestatus_a-DoubleColumn.obj `if test -f 'DoubleColumn.cc'; then $(CYGPATH_W) 'DoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DoubleColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-DoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DoubleColumn.cc' object='liblivestatus_a-DoubleColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DoubleColumn.obj `if test -f 'DoubleColumn.cc'; then $(CYGPATH_W) 'DoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DoubleColumn.cc'; fi` + +liblivestatus_a-DoubleFilter.o: DoubleFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DoubleFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DoubleFilter.Tpo -c -o liblivestatus_a-DoubleFilter.o `test -f 'DoubleFilter.cc' || echo '$(srcdir)/'`DoubleFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DoubleFilter.Tpo $(DEPDIR)/liblivestatus_a-DoubleFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DoubleFilter.cc' object='liblivestatus_a-DoubleFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DoubleFilter.o `test -f 'DoubleFilter.cc' || echo '$(srcdir)/'`DoubleFilter.cc + +liblivestatus_a-DoubleFilter.obj: DoubleFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DoubleFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DoubleFilter.Tpo -c -o liblivestatus_a-DoubleFilter.obj `if test -f 'DoubleFilter.cc'; then $(CYGPATH_W) 'DoubleFilter.cc'; else $(CYGPATH_W) '$(srcdir)/DoubleFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DoubleFilter.Tpo $(DEPDIR)/liblivestatus_a-DoubleFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DoubleFilter.cc' object='liblivestatus_a-DoubleFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DoubleFilter.obj `if test -f 'DoubleFilter.cc'; then $(CYGPATH_W) 'DoubleFilter.cc'; else $(CYGPATH_W) '$(srcdir)/DoubleFilter.cc'; fi` + +liblivestatus_a-DowntimeColumn.o: DowntimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DowntimeColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DowntimeColumn.Tpo -c -o liblivestatus_a-DowntimeColumn.o `test -f 'DowntimeColumn.cc' || echo '$(srcdir)/'`DowntimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DowntimeColumn.Tpo $(DEPDIR)/liblivestatus_a-DowntimeColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DowntimeColumn.cc' object='liblivestatus_a-DowntimeColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DowntimeColumn.o `test -f 'DowntimeColumn.cc' || echo '$(srcdir)/'`DowntimeColumn.cc + +liblivestatus_a-DowntimeColumn.obj: DowntimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DowntimeColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DowntimeColumn.Tpo -c -o liblivestatus_a-DowntimeColumn.obj `if test -f 'DowntimeColumn.cc'; then $(CYGPATH_W) 'DowntimeColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DowntimeColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DowntimeColumn.Tpo $(DEPDIR)/liblivestatus_a-DowntimeColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DowntimeColumn.cc' object='liblivestatus_a-DowntimeColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DowntimeColumn.obj `if test -f 'DowntimeColumn.cc'; then $(CYGPATH_W) 'DowntimeColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DowntimeColumn.cc'; fi` + +liblivestatus_a-DowntimeOrComment.o: DowntimeOrComment.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DowntimeOrComment.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DowntimeOrComment.Tpo -c -o liblivestatus_a-DowntimeOrComment.o `test -f 'DowntimeOrComment.cc' || echo '$(srcdir)/'`DowntimeOrComment.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DowntimeOrComment.Tpo $(DEPDIR)/liblivestatus_a-DowntimeOrComment.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DowntimeOrComment.cc' object='liblivestatus_a-DowntimeOrComment.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DowntimeOrComment.o `test -f 'DowntimeOrComment.cc' || echo '$(srcdir)/'`DowntimeOrComment.cc + +liblivestatus_a-DowntimeOrComment.obj: DowntimeOrComment.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DowntimeOrComment.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DowntimeOrComment.Tpo -c -o liblivestatus_a-DowntimeOrComment.obj `if test -f 'DowntimeOrComment.cc'; then $(CYGPATH_W) 'DowntimeOrComment.cc'; else $(CYGPATH_W) '$(srcdir)/DowntimeOrComment.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DowntimeOrComment.Tpo $(DEPDIR)/liblivestatus_a-DowntimeOrComment.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DowntimeOrComment.cc' object='liblivestatus_a-DowntimeOrComment.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DowntimeOrComment.obj `if test -f 'DowntimeOrComment.cc'; then $(CYGPATH_W) 'DowntimeOrComment.cc'; else $(CYGPATH_W) '$(srcdir)/DowntimeOrComment.cc'; fi` + +liblivestatus_a-DowntimesOrComments.o: DowntimesOrComments.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DowntimesOrComments.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DowntimesOrComments.Tpo -c -o liblivestatus_a-DowntimesOrComments.o `test -f 'DowntimesOrComments.cc' || echo '$(srcdir)/'`DowntimesOrComments.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DowntimesOrComments.Tpo $(DEPDIR)/liblivestatus_a-DowntimesOrComments.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DowntimesOrComments.cc' object='liblivestatus_a-DowntimesOrComments.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DowntimesOrComments.o `test -f 'DowntimesOrComments.cc' || echo '$(srcdir)/'`DowntimesOrComments.cc + +liblivestatus_a-DowntimesOrComments.obj: DowntimesOrComments.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DowntimesOrComments.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DowntimesOrComments.Tpo -c -o liblivestatus_a-DowntimesOrComments.obj `if test -f 'DowntimesOrComments.cc'; then $(CYGPATH_W) 'DowntimesOrComments.cc'; else $(CYGPATH_W) '$(srcdir)/DowntimesOrComments.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DowntimesOrComments.Tpo $(DEPDIR)/liblivestatus_a-DowntimesOrComments.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DowntimesOrComments.cc' object='liblivestatus_a-DowntimesOrComments.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DowntimesOrComments.obj `if test -f 'DowntimesOrComments.cc'; then $(CYGPATH_W) 'DowntimesOrComments.cc'; else $(CYGPATH_W) '$(srcdir)/DowntimesOrComments.cc'; fi` + +liblivestatus_a-DynamicColumn.o: DynamicColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DynamicColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DynamicColumn.Tpo -c -o liblivestatus_a-DynamicColumn.o `test -f 'DynamicColumn.cc' || echo '$(srcdir)/'`DynamicColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DynamicColumn.Tpo $(DEPDIR)/liblivestatus_a-DynamicColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DynamicColumn.cc' object='liblivestatus_a-DynamicColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DynamicColumn.o `test -f 'DynamicColumn.cc' || echo '$(srcdir)/'`DynamicColumn.cc + +liblivestatus_a-DynamicColumn.obj: DynamicColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DynamicColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DynamicColumn.Tpo -c -o liblivestatus_a-DynamicColumn.obj `if test -f 'DynamicColumn.cc'; then $(CYGPATH_W) 'DynamicColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DynamicColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DynamicColumn.Tpo $(DEPDIR)/liblivestatus_a-DynamicColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DynamicColumn.cc' object='liblivestatus_a-DynamicColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DynamicColumn.obj `if test -f 'DynamicColumn.cc'; then $(CYGPATH_W) 'DynamicColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DynamicColumn.cc'; fi` + +liblivestatus_a-DynamicEventConsoleReplicationColumn.o: DynamicEventConsoleReplicationColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DynamicEventConsoleReplicationColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DynamicEventConsoleReplicationColumn.Tpo -c -o liblivestatus_a-DynamicEventConsoleReplicationColumn.o `test -f 'DynamicEventConsoleReplicationColumn.cc' || echo '$(srcdir)/'`DynamicEventConsoleReplicationColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DynamicEventConsoleReplicationColumn.Tpo $(DEPDIR)/liblivestatus_a-DynamicEventConsoleReplicationColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DynamicEventConsoleReplicationColumn.cc' object='liblivestatus_a-DynamicEventConsoleReplicationColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DynamicEventConsoleReplicationColumn.o `test -f 'DynamicEventConsoleReplicationColumn.cc' || echo '$(srcdir)/'`DynamicEventConsoleReplicationColumn.cc + +liblivestatus_a-DynamicEventConsoleReplicationColumn.obj: DynamicEventConsoleReplicationColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DynamicEventConsoleReplicationColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DynamicEventConsoleReplicationColumn.Tpo -c -o liblivestatus_a-DynamicEventConsoleReplicationColumn.obj `if test -f 'DynamicEventConsoleReplicationColumn.cc'; then $(CYGPATH_W) 'DynamicEventConsoleReplicationColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DynamicEventConsoleReplicationColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DynamicEventConsoleReplicationColumn.Tpo $(DEPDIR)/liblivestatus_a-DynamicEventConsoleReplicationColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DynamicEventConsoleReplicationColumn.cc' object='liblivestatus_a-DynamicEventConsoleReplicationColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DynamicEventConsoleReplicationColumn.obj `if test -f 'DynamicEventConsoleReplicationColumn.cc'; then $(CYGPATH_W) 'DynamicEventConsoleReplicationColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DynamicEventConsoleReplicationColumn.cc'; fi` + +liblivestatus_a-DynamicLogwatchFileColumn.o: DynamicLogwatchFileColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DynamicLogwatchFileColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-DynamicLogwatchFileColumn.Tpo -c -o liblivestatus_a-DynamicLogwatchFileColumn.o `test -f 'DynamicLogwatchFileColumn.cc' || echo '$(srcdir)/'`DynamicLogwatchFileColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DynamicLogwatchFileColumn.Tpo $(DEPDIR)/liblivestatus_a-DynamicLogwatchFileColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DynamicLogwatchFileColumn.cc' object='liblivestatus_a-DynamicLogwatchFileColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DynamicLogwatchFileColumn.o `test -f 'DynamicLogwatchFileColumn.cc' || echo '$(srcdir)/'`DynamicLogwatchFileColumn.cc + +liblivestatus_a-DynamicLogwatchFileColumn.obj: DynamicLogwatchFileColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-DynamicLogwatchFileColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-DynamicLogwatchFileColumn.Tpo -c -o liblivestatus_a-DynamicLogwatchFileColumn.obj `if test -f 'DynamicLogwatchFileColumn.cc'; then $(CYGPATH_W) 'DynamicLogwatchFileColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DynamicLogwatchFileColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-DynamicLogwatchFileColumn.Tpo $(DEPDIR)/liblivestatus_a-DynamicLogwatchFileColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='DynamicLogwatchFileColumn.cc' object='liblivestatus_a-DynamicLogwatchFileColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-DynamicLogwatchFileColumn.obj `if test -f 'DynamicLogwatchFileColumn.cc'; then $(CYGPATH_W) 'DynamicLogwatchFileColumn.cc'; else $(CYGPATH_W) '$(srcdir)/DynamicLogwatchFileColumn.cc'; fi` + +liblivestatus_a-EventConsoleConnection.o: EventConsoleConnection.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-EventConsoleConnection.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-EventConsoleConnection.Tpo -c -o liblivestatus_a-EventConsoleConnection.o `test -f 'EventConsoleConnection.cc' || echo '$(srcdir)/'`EventConsoleConnection.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-EventConsoleConnection.Tpo $(DEPDIR)/liblivestatus_a-EventConsoleConnection.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='EventConsoleConnection.cc' object='liblivestatus_a-EventConsoleConnection.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-EventConsoleConnection.o `test -f 'EventConsoleConnection.cc' || echo '$(srcdir)/'`EventConsoleConnection.cc + +liblivestatus_a-EventConsoleConnection.obj: EventConsoleConnection.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-EventConsoleConnection.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-EventConsoleConnection.Tpo -c -o liblivestatus_a-EventConsoleConnection.obj `if test -f 'EventConsoleConnection.cc'; then $(CYGPATH_W) 'EventConsoleConnection.cc'; else $(CYGPATH_W) '$(srcdir)/EventConsoleConnection.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-EventConsoleConnection.Tpo $(DEPDIR)/liblivestatus_a-EventConsoleConnection.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='EventConsoleConnection.cc' object='liblivestatus_a-EventConsoleConnection.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-EventConsoleConnection.obj `if test -f 'EventConsoleConnection.cc'; then $(CYGPATH_W) 'EventConsoleConnection.cc'; else $(CYGPATH_W) '$(srcdir)/EventConsoleConnection.cc'; fi` + +liblivestatus_a-Filter.o: Filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Filter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Filter.Tpo -c -o liblivestatus_a-Filter.o `test -f 'Filter.cc' || echo '$(srcdir)/'`Filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Filter.Tpo $(DEPDIR)/liblivestatus_a-Filter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Filter.cc' object='liblivestatus_a-Filter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Filter.o `test -f 'Filter.cc' || echo '$(srcdir)/'`Filter.cc + +liblivestatus_a-Filter.obj: Filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Filter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Filter.Tpo -c -o liblivestatus_a-Filter.obj `if test -f 'Filter.cc'; then $(CYGPATH_W) 'Filter.cc'; else $(CYGPATH_W) '$(srcdir)/Filter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Filter.Tpo $(DEPDIR)/liblivestatus_a-Filter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Filter.cc' object='liblivestatus_a-Filter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Filter.obj `if test -f 'Filter.cc'; then $(CYGPATH_W) 'Filter.cc'; else $(CYGPATH_W) '$(srcdir)/Filter.cc'; fi` + +liblivestatus_a-HostContactsColumn.o: HostContactsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostContactsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostContactsColumn.Tpo -c -o liblivestatus_a-HostContactsColumn.o `test -f 'HostContactsColumn.cc' || echo '$(srcdir)/'`HostContactsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostContactsColumn.Tpo $(DEPDIR)/liblivestatus_a-HostContactsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostContactsColumn.cc' object='liblivestatus_a-HostContactsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostContactsColumn.o `test -f 'HostContactsColumn.cc' || echo '$(srcdir)/'`HostContactsColumn.cc + +liblivestatus_a-HostContactsColumn.obj: HostContactsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostContactsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostContactsColumn.Tpo -c -o liblivestatus_a-HostContactsColumn.obj `if test -f 'HostContactsColumn.cc'; then $(CYGPATH_W) 'HostContactsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostContactsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostContactsColumn.Tpo $(DEPDIR)/liblivestatus_a-HostContactsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostContactsColumn.cc' object='liblivestatus_a-HostContactsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostContactsColumn.obj `if test -f 'HostContactsColumn.cc'; then $(CYGPATH_W) 'HostContactsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostContactsColumn.cc'; fi` + +liblivestatus_a-HostFileColumn.o: HostFileColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostFileColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostFileColumn.Tpo -c -o liblivestatus_a-HostFileColumn.o `test -f 'HostFileColumn.cc' || echo '$(srcdir)/'`HostFileColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostFileColumn.Tpo $(DEPDIR)/liblivestatus_a-HostFileColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostFileColumn.cc' object='liblivestatus_a-HostFileColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostFileColumn.o `test -f 'HostFileColumn.cc' || echo '$(srcdir)/'`HostFileColumn.cc + +liblivestatus_a-HostFileColumn.obj: HostFileColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostFileColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostFileColumn.Tpo -c -o liblivestatus_a-HostFileColumn.obj `if test -f 'HostFileColumn.cc'; then $(CYGPATH_W) 'HostFileColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostFileColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostFileColumn.Tpo $(DEPDIR)/liblivestatus_a-HostFileColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostFileColumn.cc' object='liblivestatus_a-HostFileColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostFileColumn.obj `if test -f 'HostFileColumn.cc'; then $(CYGPATH_W) 'HostFileColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostFileColumn.cc'; fi` + +liblivestatus_a-HostGroupsColumn.o: HostGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostGroupsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostGroupsColumn.Tpo -c -o liblivestatus_a-HostGroupsColumn.o `test -f 'HostGroupsColumn.cc' || echo '$(srcdir)/'`HostGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostGroupsColumn.Tpo $(DEPDIR)/liblivestatus_a-HostGroupsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostGroupsColumn.cc' object='liblivestatus_a-HostGroupsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostGroupsColumn.o `test -f 'HostGroupsColumn.cc' || echo '$(srcdir)/'`HostGroupsColumn.cc + +liblivestatus_a-HostGroupsColumn.obj: HostGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostGroupsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostGroupsColumn.Tpo -c -o liblivestatus_a-HostGroupsColumn.obj `if test -f 'HostGroupsColumn.cc'; then $(CYGPATH_W) 'HostGroupsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostGroupsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostGroupsColumn.Tpo $(DEPDIR)/liblivestatus_a-HostGroupsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostGroupsColumn.cc' object='liblivestatus_a-HostGroupsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostGroupsColumn.obj `if test -f 'HostGroupsColumn.cc'; then $(CYGPATH_W) 'HostGroupsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostGroupsColumn.cc'; fi` + +liblivestatus_a-HostListColumn.o: HostListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostListColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostListColumn.Tpo -c -o liblivestatus_a-HostListColumn.o `test -f 'HostListColumn.cc' || echo '$(srcdir)/'`HostListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostListColumn.Tpo $(DEPDIR)/liblivestatus_a-HostListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostListColumn.cc' object='liblivestatus_a-HostListColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostListColumn.o `test -f 'HostListColumn.cc' || echo '$(srcdir)/'`HostListColumn.cc + +liblivestatus_a-HostListColumn.obj: HostListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostListColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostListColumn.Tpo -c -o liblivestatus_a-HostListColumn.obj `if test -f 'HostListColumn.cc'; then $(CYGPATH_W) 'HostListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostListColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostListColumn.Tpo $(DEPDIR)/liblivestatus_a-HostListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostListColumn.cc' object='liblivestatus_a-HostListColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostListColumn.obj `if test -f 'HostListColumn.cc'; then $(CYGPATH_W) 'HostListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostListColumn.cc'; fi` + +liblivestatus_a-HostListStateColumn.o: HostListStateColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostListStateColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostListStateColumn.Tpo -c -o liblivestatus_a-HostListStateColumn.o `test -f 'HostListStateColumn.cc' || echo '$(srcdir)/'`HostListStateColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostListStateColumn.Tpo $(DEPDIR)/liblivestatus_a-HostListStateColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostListStateColumn.cc' object='liblivestatus_a-HostListStateColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostListStateColumn.o `test -f 'HostListStateColumn.cc' || echo '$(srcdir)/'`HostListStateColumn.cc + +liblivestatus_a-HostListStateColumn.obj: HostListStateColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostListStateColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostListStateColumn.Tpo -c -o liblivestatus_a-HostListStateColumn.obj `if test -f 'HostListStateColumn.cc'; then $(CYGPATH_W) 'HostListStateColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostListStateColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostListStateColumn.Tpo $(DEPDIR)/liblivestatus_a-HostListStateColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostListStateColumn.cc' object='liblivestatus_a-HostListStateColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostListStateColumn.obj `if test -f 'HostListStateColumn.cc'; then $(CYGPATH_W) 'HostListStateColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostListStateColumn.cc'; fi` + +liblivestatus_a-HostServiceState.o: HostServiceState.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostServiceState.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostServiceState.Tpo -c -o liblivestatus_a-HostServiceState.o `test -f 'HostServiceState.cc' || echo '$(srcdir)/'`HostServiceState.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostServiceState.Tpo $(DEPDIR)/liblivestatus_a-HostServiceState.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostServiceState.cc' object='liblivestatus_a-HostServiceState.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostServiceState.o `test -f 'HostServiceState.cc' || echo '$(srcdir)/'`HostServiceState.cc + +liblivestatus_a-HostServiceState.obj: HostServiceState.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostServiceState.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostServiceState.Tpo -c -o liblivestatus_a-HostServiceState.obj `if test -f 'HostServiceState.cc'; then $(CYGPATH_W) 'HostServiceState.cc'; else $(CYGPATH_W) '$(srcdir)/HostServiceState.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostServiceState.Tpo $(DEPDIR)/liblivestatus_a-HostServiceState.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostServiceState.cc' object='liblivestatus_a-HostServiceState.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostServiceState.obj `if test -f 'HostServiceState.cc'; then $(CYGPATH_W) 'HostServiceState.cc'; else $(CYGPATH_W) '$(srcdir)/HostServiceState.cc'; fi` + +liblivestatus_a-HostSpecialDoubleColumn.o: HostSpecialDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostSpecialDoubleColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostSpecialDoubleColumn.Tpo -c -o liblivestatus_a-HostSpecialDoubleColumn.o `test -f 'HostSpecialDoubleColumn.cc' || echo '$(srcdir)/'`HostSpecialDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostSpecialDoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-HostSpecialDoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostSpecialDoubleColumn.cc' object='liblivestatus_a-HostSpecialDoubleColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostSpecialDoubleColumn.o `test -f 'HostSpecialDoubleColumn.cc' || echo '$(srcdir)/'`HostSpecialDoubleColumn.cc + +liblivestatus_a-HostSpecialDoubleColumn.obj: HostSpecialDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostSpecialDoubleColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostSpecialDoubleColumn.Tpo -c -o liblivestatus_a-HostSpecialDoubleColumn.obj `if test -f 'HostSpecialDoubleColumn.cc'; then $(CYGPATH_W) 'HostSpecialDoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostSpecialDoubleColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostSpecialDoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-HostSpecialDoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostSpecialDoubleColumn.cc' object='liblivestatus_a-HostSpecialDoubleColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostSpecialDoubleColumn.obj `if test -f 'HostSpecialDoubleColumn.cc'; then $(CYGPATH_W) 'HostSpecialDoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostSpecialDoubleColumn.cc'; fi` + +liblivestatus_a-HostSpecialIntColumn.o: HostSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostSpecialIntColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostSpecialIntColumn.Tpo -c -o liblivestatus_a-HostSpecialIntColumn.o `test -f 'HostSpecialIntColumn.cc' || echo '$(srcdir)/'`HostSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostSpecialIntColumn.Tpo $(DEPDIR)/liblivestatus_a-HostSpecialIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostSpecialIntColumn.cc' object='liblivestatus_a-HostSpecialIntColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostSpecialIntColumn.o `test -f 'HostSpecialIntColumn.cc' || echo '$(srcdir)/'`HostSpecialIntColumn.cc + +liblivestatus_a-HostSpecialIntColumn.obj: HostSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-HostSpecialIntColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-HostSpecialIntColumn.Tpo -c -o liblivestatus_a-HostSpecialIntColumn.obj `if test -f 'HostSpecialIntColumn.cc'; then $(CYGPATH_W) 'HostSpecialIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostSpecialIntColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-HostSpecialIntColumn.Tpo $(DEPDIR)/liblivestatus_a-HostSpecialIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='HostSpecialIntColumn.cc' object='liblivestatus_a-HostSpecialIntColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-HostSpecialIntColumn.obj `if test -f 'HostSpecialIntColumn.cc'; then $(CYGPATH_W) 'HostSpecialIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/HostSpecialIntColumn.cc'; fi` + +liblivestatus_a-InputBuffer.o: InputBuffer.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-InputBuffer.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-InputBuffer.Tpo -c -o liblivestatus_a-InputBuffer.o `test -f 'InputBuffer.cc' || echo '$(srcdir)/'`InputBuffer.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-InputBuffer.Tpo $(DEPDIR)/liblivestatus_a-InputBuffer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InputBuffer.cc' object='liblivestatus_a-InputBuffer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-InputBuffer.o `test -f 'InputBuffer.cc' || echo '$(srcdir)/'`InputBuffer.cc + +liblivestatus_a-InputBuffer.obj: InputBuffer.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-InputBuffer.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-InputBuffer.Tpo -c -o liblivestatus_a-InputBuffer.obj `if test -f 'InputBuffer.cc'; then $(CYGPATH_W) 'InputBuffer.cc'; else $(CYGPATH_W) '$(srcdir)/InputBuffer.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-InputBuffer.Tpo $(DEPDIR)/liblivestatus_a-InputBuffer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='InputBuffer.cc' object='liblivestatus_a-InputBuffer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-InputBuffer.obj `if test -f 'InputBuffer.cc'; then $(CYGPATH_W) 'InputBuffer.cc'; else $(CYGPATH_W) '$(srcdir)/InputBuffer.cc'; fi` + +liblivestatus_a-IntColumn.o: IntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-IntColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-IntColumn.Tpo -c -o liblivestatus_a-IntColumn.o `test -f 'IntColumn.cc' || echo '$(srcdir)/'`IntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-IntColumn.Tpo $(DEPDIR)/liblivestatus_a-IntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='IntColumn.cc' object='liblivestatus_a-IntColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-IntColumn.o `test -f 'IntColumn.cc' || echo '$(srcdir)/'`IntColumn.cc + +liblivestatus_a-IntColumn.obj: IntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-IntColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-IntColumn.Tpo -c -o liblivestatus_a-IntColumn.obj `if test -f 'IntColumn.cc'; then $(CYGPATH_W) 'IntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/IntColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-IntColumn.Tpo $(DEPDIR)/liblivestatus_a-IntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='IntColumn.cc' object='liblivestatus_a-IntColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-IntColumn.obj `if test -f 'IntColumn.cc'; then $(CYGPATH_W) 'IntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/IntColumn.cc'; fi` + +liblivestatus_a-IntFilter.o: IntFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-IntFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-IntFilter.Tpo -c -o liblivestatus_a-IntFilter.o `test -f 'IntFilter.cc' || echo '$(srcdir)/'`IntFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-IntFilter.Tpo $(DEPDIR)/liblivestatus_a-IntFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='IntFilter.cc' object='liblivestatus_a-IntFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-IntFilter.o `test -f 'IntFilter.cc' || echo '$(srcdir)/'`IntFilter.cc + +liblivestatus_a-IntFilter.obj: IntFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-IntFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-IntFilter.Tpo -c -o liblivestatus_a-IntFilter.obj `if test -f 'IntFilter.cc'; then $(CYGPATH_W) 'IntFilter.cc'; else $(CYGPATH_W) '$(srcdir)/IntFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-IntFilter.Tpo $(DEPDIR)/liblivestatus_a-IntFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='IntFilter.cc' object='liblivestatus_a-IntFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-IntFilter.obj `if test -f 'IntFilter.cc'; then $(CYGPATH_W) 'IntFilter.cc'; else $(CYGPATH_W) '$(srcdir)/IntFilter.cc'; fi` + +liblivestatus_a-ListColumn.o: ListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ListColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ListColumn.Tpo -c -o liblivestatus_a-ListColumn.o `test -f 'ListColumn.cc' || echo '$(srcdir)/'`ListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ListColumn.Tpo $(DEPDIR)/liblivestatus_a-ListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ListColumn.cc' object='liblivestatus_a-ListColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ListColumn.o `test -f 'ListColumn.cc' || echo '$(srcdir)/'`ListColumn.cc + +liblivestatus_a-ListColumn.obj: ListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ListColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ListColumn.Tpo -c -o liblivestatus_a-ListColumn.obj `if test -f 'ListColumn.cc'; then $(CYGPATH_W) 'ListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ListColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ListColumn.Tpo $(DEPDIR)/liblivestatus_a-ListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ListColumn.cc' object='liblivestatus_a-ListColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ListColumn.obj `if test -f 'ListColumn.cc'; then $(CYGPATH_W) 'ListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ListColumn.cc'; fi` + +liblivestatus_a-ListFilter.o: ListFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ListFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ListFilter.Tpo -c -o liblivestatus_a-ListFilter.o `test -f 'ListFilter.cc' || echo '$(srcdir)/'`ListFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ListFilter.Tpo $(DEPDIR)/liblivestatus_a-ListFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ListFilter.cc' object='liblivestatus_a-ListFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ListFilter.o `test -f 'ListFilter.cc' || echo '$(srcdir)/'`ListFilter.cc + +liblivestatus_a-ListFilter.obj: ListFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ListFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ListFilter.Tpo -c -o liblivestatus_a-ListFilter.obj `if test -f 'ListFilter.cc'; then $(CYGPATH_W) 'ListFilter.cc'; else $(CYGPATH_W) '$(srcdir)/ListFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ListFilter.Tpo $(DEPDIR)/liblivestatus_a-ListFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ListFilter.cc' object='liblivestatus_a-ListFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ListFilter.obj `if test -f 'ListFilter.cc'; then $(CYGPATH_W) 'ListFilter.cc'; else $(CYGPATH_W) '$(srcdir)/ListFilter.cc'; fi` + +liblivestatus_a-LogCache.o: LogCache.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-LogCache.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-LogCache.Tpo -c -o liblivestatus_a-LogCache.o `test -f 'LogCache.cc' || echo '$(srcdir)/'`LogCache.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-LogCache.Tpo $(DEPDIR)/liblivestatus_a-LogCache.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LogCache.cc' object='liblivestatus_a-LogCache.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-LogCache.o `test -f 'LogCache.cc' || echo '$(srcdir)/'`LogCache.cc + +liblivestatus_a-LogCache.obj: LogCache.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-LogCache.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-LogCache.Tpo -c -o liblivestatus_a-LogCache.obj `if test -f 'LogCache.cc'; then $(CYGPATH_W) 'LogCache.cc'; else $(CYGPATH_W) '$(srcdir)/LogCache.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-LogCache.Tpo $(DEPDIR)/liblivestatus_a-LogCache.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LogCache.cc' object='liblivestatus_a-LogCache.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-LogCache.obj `if test -f 'LogCache.cc'; then $(CYGPATH_W) 'LogCache.cc'; else $(CYGPATH_W) '$(srcdir)/LogCache.cc'; fi` + +liblivestatus_a-LogEntry.o: LogEntry.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-LogEntry.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-LogEntry.Tpo -c -o liblivestatus_a-LogEntry.o `test -f 'LogEntry.cc' || echo '$(srcdir)/'`LogEntry.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-LogEntry.Tpo $(DEPDIR)/liblivestatus_a-LogEntry.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LogEntry.cc' object='liblivestatus_a-LogEntry.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-LogEntry.o `test -f 'LogEntry.cc' || echo '$(srcdir)/'`LogEntry.cc + +liblivestatus_a-LogEntry.obj: LogEntry.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-LogEntry.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-LogEntry.Tpo -c -o liblivestatus_a-LogEntry.obj `if test -f 'LogEntry.cc'; then $(CYGPATH_W) 'LogEntry.cc'; else $(CYGPATH_W) '$(srcdir)/LogEntry.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-LogEntry.Tpo $(DEPDIR)/liblivestatus_a-LogEntry.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LogEntry.cc' object='liblivestatus_a-LogEntry.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-LogEntry.obj `if test -f 'LogEntry.cc'; then $(CYGPATH_W) 'LogEntry.cc'; else $(CYGPATH_W) '$(srcdir)/LogEntry.cc'; fi` + +liblivestatus_a-Logfile.o: Logfile.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Logfile.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Logfile.Tpo -c -o liblivestatus_a-Logfile.o `test -f 'Logfile.cc' || echo '$(srcdir)/'`Logfile.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Logfile.Tpo $(DEPDIR)/liblivestatus_a-Logfile.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Logfile.cc' object='liblivestatus_a-Logfile.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Logfile.o `test -f 'Logfile.cc' || echo '$(srcdir)/'`Logfile.cc + +liblivestatus_a-Logfile.obj: Logfile.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Logfile.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Logfile.Tpo -c -o liblivestatus_a-Logfile.obj `if test -f 'Logfile.cc'; then $(CYGPATH_W) 'Logfile.cc'; else $(CYGPATH_W) '$(srcdir)/Logfile.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Logfile.Tpo $(DEPDIR)/liblivestatus_a-Logfile.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Logfile.cc' object='liblivestatus_a-Logfile.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Logfile.obj `if test -f 'Logfile.cc'; then $(CYGPATH_W) 'Logfile.cc'; else $(CYGPATH_W) '$(srcdir)/Logfile.cc'; fi` + +liblivestatus_a-Logger.o: Logger.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Logger.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Logger.Tpo -c -o liblivestatus_a-Logger.o `test -f 'Logger.cc' || echo '$(srcdir)/'`Logger.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Logger.Tpo $(DEPDIR)/liblivestatus_a-Logger.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Logger.cc' object='liblivestatus_a-Logger.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Logger.o `test -f 'Logger.cc' || echo '$(srcdir)/'`Logger.cc + +liblivestatus_a-Logger.obj: Logger.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Logger.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Logger.Tpo -c -o liblivestatus_a-Logger.obj `if test -f 'Logger.cc'; then $(CYGPATH_W) 'Logger.cc'; else $(CYGPATH_W) '$(srcdir)/Logger.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Logger.Tpo $(DEPDIR)/liblivestatus_a-Logger.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Logger.cc' object='liblivestatus_a-Logger.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Logger.obj `if test -f 'Logger.cc'; then $(CYGPATH_W) 'Logger.cc'; else $(CYGPATH_W) '$(srcdir)/Logger.cc'; fi` + +liblivestatus_a-LogwatchListColumn.o: LogwatchListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-LogwatchListColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-LogwatchListColumn.Tpo -c -o liblivestatus_a-LogwatchListColumn.o `test -f 'LogwatchListColumn.cc' || echo '$(srcdir)/'`LogwatchListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-LogwatchListColumn.Tpo $(DEPDIR)/liblivestatus_a-LogwatchListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LogwatchListColumn.cc' object='liblivestatus_a-LogwatchListColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-LogwatchListColumn.o `test -f 'LogwatchListColumn.cc' || echo '$(srcdir)/'`LogwatchListColumn.cc + +liblivestatus_a-LogwatchListColumn.obj: LogwatchListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-LogwatchListColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-LogwatchListColumn.Tpo -c -o liblivestatus_a-LogwatchListColumn.obj `if test -f 'LogwatchListColumn.cc'; then $(CYGPATH_W) 'LogwatchListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/LogwatchListColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-LogwatchListColumn.Tpo $(DEPDIR)/liblivestatus_a-LogwatchListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LogwatchListColumn.cc' object='liblivestatus_a-LogwatchListColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-LogwatchListColumn.obj `if test -f 'LogwatchListColumn.cc'; then $(CYGPATH_W) 'LogwatchListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/LogwatchListColumn.cc'; fi` + +liblivestatus_a-MetricsColumn.o: MetricsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-MetricsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-MetricsColumn.Tpo -c -o liblivestatus_a-MetricsColumn.o `test -f 'MetricsColumn.cc' || echo '$(srcdir)/'`MetricsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-MetricsColumn.Tpo $(DEPDIR)/liblivestatus_a-MetricsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MetricsColumn.cc' object='liblivestatus_a-MetricsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-MetricsColumn.o `test -f 'MetricsColumn.cc' || echo '$(srcdir)/'`MetricsColumn.cc + +liblivestatus_a-MetricsColumn.obj: MetricsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-MetricsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-MetricsColumn.Tpo -c -o liblivestatus_a-MetricsColumn.obj `if test -f 'MetricsColumn.cc'; then $(CYGPATH_W) 'MetricsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/MetricsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-MetricsColumn.Tpo $(DEPDIR)/liblivestatus_a-MetricsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='MetricsColumn.cc' object='liblivestatus_a-MetricsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-MetricsColumn.obj `if test -f 'MetricsColumn.cc'; then $(CYGPATH_W) 'MetricsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/MetricsColumn.cc'; fi` + +liblivestatus_a-NullColumn.o: NullColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-NullColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-NullColumn.Tpo -c -o liblivestatus_a-NullColumn.o `test -f 'NullColumn.cc' || echo '$(srcdir)/'`NullColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-NullColumn.Tpo $(DEPDIR)/liblivestatus_a-NullColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='NullColumn.cc' object='liblivestatus_a-NullColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-NullColumn.o `test -f 'NullColumn.cc' || echo '$(srcdir)/'`NullColumn.cc + +liblivestatus_a-NullColumn.obj: NullColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-NullColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-NullColumn.Tpo -c -o liblivestatus_a-NullColumn.obj `if test -f 'NullColumn.cc'; then $(CYGPATH_W) 'NullColumn.cc'; else $(CYGPATH_W) '$(srcdir)/NullColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-NullColumn.Tpo $(DEPDIR)/liblivestatus_a-NullColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='NullColumn.cc' object='liblivestatus_a-NullColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-NullColumn.obj `if test -f 'NullColumn.cc'; then $(CYGPATH_W) 'NullColumn.cc'; else $(CYGPATH_W) '$(srcdir)/NullColumn.cc'; fi` + +liblivestatus_a-OffsetBoolColumn.o: OffsetBoolColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetBoolColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetBoolColumn.Tpo -c -o liblivestatus_a-OffsetBoolColumn.o `test -f 'OffsetBoolColumn.cc' || echo '$(srcdir)/'`OffsetBoolColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetBoolColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetBoolColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetBoolColumn.cc' object='liblivestatus_a-OffsetBoolColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetBoolColumn.o `test -f 'OffsetBoolColumn.cc' || echo '$(srcdir)/'`OffsetBoolColumn.cc + +liblivestatus_a-OffsetBoolColumn.obj: OffsetBoolColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetBoolColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetBoolColumn.Tpo -c -o liblivestatus_a-OffsetBoolColumn.obj `if test -f 'OffsetBoolColumn.cc'; then $(CYGPATH_W) 'OffsetBoolColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetBoolColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetBoolColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetBoolColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetBoolColumn.cc' object='liblivestatus_a-OffsetBoolColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetBoolColumn.obj `if test -f 'OffsetBoolColumn.cc'; then $(CYGPATH_W) 'OffsetBoolColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetBoolColumn.cc'; fi` + +liblivestatus_a-OffsetDoubleColumn.o: OffsetDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetDoubleColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetDoubleColumn.Tpo -c -o liblivestatus_a-OffsetDoubleColumn.o `test -f 'OffsetDoubleColumn.cc' || echo '$(srcdir)/'`OffsetDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetDoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetDoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetDoubleColumn.cc' object='liblivestatus_a-OffsetDoubleColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetDoubleColumn.o `test -f 'OffsetDoubleColumn.cc' || echo '$(srcdir)/'`OffsetDoubleColumn.cc + +liblivestatus_a-OffsetDoubleColumn.obj: OffsetDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetDoubleColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetDoubleColumn.Tpo -c -o liblivestatus_a-OffsetDoubleColumn.obj `if test -f 'OffsetDoubleColumn.cc'; then $(CYGPATH_W) 'OffsetDoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetDoubleColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetDoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetDoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetDoubleColumn.cc' object='liblivestatus_a-OffsetDoubleColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetDoubleColumn.obj `if test -f 'OffsetDoubleColumn.cc'; then $(CYGPATH_W) 'OffsetDoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetDoubleColumn.cc'; fi` + +liblivestatus_a-OffsetIntColumn.o: OffsetIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetIntColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetIntColumn.Tpo -c -o liblivestatus_a-OffsetIntColumn.o `test -f 'OffsetIntColumn.cc' || echo '$(srcdir)/'`OffsetIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetIntColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetIntColumn.cc' object='liblivestatus_a-OffsetIntColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetIntColumn.o `test -f 'OffsetIntColumn.cc' || echo '$(srcdir)/'`OffsetIntColumn.cc + +liblivestatus_a-OffsetIntColumn.obj: OffsetIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetIntColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetIntColumn.Tpo -c -o liblivestatus_a-OffsetIntColumn.obj `if test -f 'OffsetIntColumn.cc'; then $(CYGPATH_W) 'OffsetIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetIntColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetIntColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetIntColumn.cc' object='liblivestatus_a-OffsetIntColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetIntColumn.obj `if test -f 'OffsetIntColumn.cc'; then $(CYGPATH_W) 'OffsetIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetIntColumn.cc'; fi` + +liblivestatus_a-OffsetPerfdataColumn.o: OffsetPerfdataColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetPerfdataColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetPerfdataColumn.Tpo -c -o liblivestatus_a-OffsetPerfdataColumn.o `test -f 'OffsetPerfdataColumn.cc' || echo '$(srcdir)/'`OffsetPerfdataColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetPerfdataColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetPerfdataColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetPerfdataColumn.cc' object='liblivestatus_a-OffsetPerfdataColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetPerfdataColumn.o `test -f 'OffsetPerfdataColumn.cc' || echo '$(srcdir)/'`OffsetPerfdataColumn.cc + +liblivestatus_a-OffsetPerfdataColumn.obj: OffsetPerfdataColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetPerfdataColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetPerfdataColumn.Tpo -c -o liblivestatus_a-OffsetPerfdataColumn.obj `if test -f 'OffsetPerfdataColumn.cc'; then $(CYGPATH_W) 'OffsetPerfdataColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetPerfdataColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetPerfdataColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetPerfdataColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetPerfdataColumn.cc' object='liblivestatus_a-OffsetPerfdataColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetPerfdataColumn.obj `if test -f 'OffsetPerfdataColumn.cc'; then $(CYGPATH_W) 'OffsetPerfdataColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetPerfdataColumn.cc'; fi` + +liblivestatus_a-OffsetSStringColumn.o: OffsetSStringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetSStringColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetSStringColumn.Tpo -c -o liblivestatus_a-OffsetSStringColumn.o `test -f 'OffsetSStringColumn.cc' || echo '$(srcdir)/'`OffsetSStringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetSStringColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetSStringColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetSStringColumn.cc' object='liblivestatus_a-OffsetSStringColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetSStringColumn.o `test -f 'OffsetSStringColumn.cc' || echo '$(srcdir)/'`OffsetSStringColumn.cc + +liblivestatus_a-OffsetSStringColumn.obj: OffsetSStringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetSStringColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetSStringColumn.Tpo -c -o liblivestatus_a-OffsetSStringColumn.obj `if test -f 'OffsetSStringColumn.cc'; then $(CYGPATH_W) 'OffsetSStringColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetSStringColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetSStringColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetSStringColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetSStringColumn.cc' object='liblivestatus_a-OffsetSStringColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetSStringColumn.obj `if test -f 'OffsetSStringColumn.cc'; then $(CYGPATH_W) 'OffsetSStringColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetSStringColumn.cc'; fi` + +liblivestatus_a-OffsetStringColumn.o: OffsetStringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringColumn.Tpo -c -o liblivestatus_a-OffsetStringColumn.o `test -f 'OffsetStringColumn.cc' || echo '$(srcdir)/'`OffsetStringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringColumn.cc' object='liblivestatus_a-OffsetStringColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringColumn.o `test -f 'OffsetStringColumn.cc' || echo '$(srcdir)/'`OffsetStringColumn.cc + +liblivestatus_a-OffsetStringColumn.obj: OffsetStringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringColumn.Tpo -c -o liblivestatus_a-OffsetStringColumn.obj `if test -f 'OffsetStringColumn.cc'; then $(CYGPATH_W) 'OffsetStringColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringColumn.cc' object='liblivestatus_a-OffsetStringColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringColumn.obj `if test -f 'OffsetStringColumn.cc'; then $(CYGPATH_W) 'OffsetStringColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringColumn.cc'; fi` + +liblivestatus_a-OffsetStringHostMacroColumn.o: OffsetStringHostMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringHostMacroColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringHostMacroColumn.Tpo -c -o liblivestatus_a-OffsetStringHostMacroColumn.o `test -f 'OffsetStringHostMacroColumn.cc' || echo '$(srcdir)/'`OffsetStringHostMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringHostMacroColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringHostMacroColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringHostMacroColumn.cc' object='liblivestatus_a-OffsetStringHostMacroColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringHostMacroColumn.o `test -f 'OffsetStringHostMacroColumn.cc' || echo '$(srcdir)/'`OffsetStringHostMacroColumn.cc + +liblivestatus_a-OffsetStringHostMacroColumn.obj: OffsetStringHostMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringHostMacroColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringHostMacroColumn.Tpo -c -o liblivestatus_a-OffsetStringHostMacroColumn.obj `if test -f 'OffsetStringHostMacroColumn.cc'; then $(CYGPATH_W) 'OffsetStringHostMacroColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringHostMacroColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringHostMacroColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringHostMacroColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringHostMacroColumn.cc' object='liblivestatus_a-OffsetStringHostMacroColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringHostMacroColumn.obj `if test -f 'OffsetStringHostMacroColumn.cc'; then $(CYGPATH_W) 'OffsetStringHostMacroColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringHostMacroColumn.cc'; fi` + +liblivestatus_a-OffsetStringMacroColumn.o: OffsetStringMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringMacroColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringMacroColumn.Tpo -c -o liblivestatus_a-OffsetStringMacroColumn.o `test -f 'OffsetStringMacroColumn.cc' || echo '$(srcdir)/'`OffsetStringMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringMacroColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringMacroColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringMacroColumn.cc' object='liblivestatus_a-OffsetStringMacroColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringMacroColumn.o `test -f 'OffsetStringMacroColumn.cc' || echo '$(srcdir)/'`OffsetStringMacroColumn.cc + +liblivestatus_a-OffsetStringMacroColumn.obj: OffsetStringMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringMacroColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringMacroColumn.Tpo -c -o liblivestatus_a-OffsetStringMacroColumn.obj `if test -f 'OffsetStringMacroColumn.cc'; then $(CYGPATH_W) 'OffsetStringMacroColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringMacroColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringMacroColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringMacroColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringMacroColumn.cc' object='liblivestatus_a-OffsetStringMacroColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringMacroColumn.obj `if test -f 'OffsetStringMacroColumn.cc'; then $(CYGPATH_W) 'OffsetStringMacroColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringMacroColumn.cc'; fi` + +liblivestatus_a-OffsetStringServiceMacroColumn.o: OffsetStringServiceMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringServiceMacroColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringServiceMacroColumn.Tpo -c -o liblivestatus_a-OffsetStringServiceMacroColumn.o `test -f 'OffsetStringServiceMacroColumn.cc' || echo '$(srcdir)/'`OffsetStringServiceMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringServiceMacroColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringServiceMacroColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringServiceMacroColumn.cc' object='liblivestatus_a-OffsetStringServiceMacroColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringServiceMacroColumn.o `test -f 'OffsetStringServiceMacroColumn.cc' || echo '$(srcdir)/'`OffsetStringServiceMacroColumn.cc + +liblivestatus_a-OffsetStringServiceMacroColumn.obj: OffsetStringServiceMacroColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetStringServiceMacroColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetStringServiceMacroColumn.Tpo -c -o liblivestatus_a-OffsetStringServiceMacroColumn.obj `if test -f 'OffsetStringServiceMacroColumn.cc'; then $(CYGPATH_W) 'OffsetStringServiceMacroColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringServiceMacroColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetStringServiceMacroColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetStringServiceMacroColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetStringServiceMacroColumn.cc' object='liblivestatus_a-OffsetStringServiceMacroColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetStringServiceMacroColumn.obj `if test -f 'OffsetStringServiceMacroColumn.cc'; then $(CYGPATH_W) 'OffsetStringServiceMacroColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetStringServiceMacroColumn.cc'; fi` + +liblivestatus_a-OffsetTimeColumn.o: OffsetTimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetTimeColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetTimeColumn.Tpo -c -o liblivestatus_a-OffsetTimeColumn.o `test -f 'OffsetTimeColumn.cc' || echo '$(srcdir)/'`OffsetTimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetTimeColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetTimeColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetTimeColumn.cc' object='liblivestatus_a-OffsetTimeColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetTimeColumn.o `test -f 'OffsetTimeColumn.cc' || echo '$(srcdir)/'`OffsetTimeColumn.cc + +liblivestatus_a-OffsetTimeColumn.obj: OffsetTimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OffsetTimeColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OffsetTimeColumn.Tpo -c -o liblivestatus_a-OffsetTimeColumn.obj `if test -f 'OffsetTimeColumn.cc'; then $(CYGPATH_W) 'OffsetTimeColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetTimeColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OffsetTimeColumn.Tpo $(DEPDIR)/liblivestatus_a-OffsetTimeColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OffsetTimeColumn.cc' object='liblivestatus_a-OffsetTimeColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OffsetTimeColumn.obj `if test -f 'OffsetTimeColumn.cc'; then $(CYGPATH_W) 'OffsetTimeColumn.cc'; else $(CYGPATH_W) '$(srcdir)/OffsetTimeColumn.cc'; fi` + +liblivestatus_a-OringFilter.o: OringFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OringFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OringFilter.Tpo -c -o liblivestatus_a-OringFilter.o `test -f 'OringFilter.cc' || echo '$(srcdir)/'`OringFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OringFilter.Tpo $(DEPDIR)/liblivestatus_a-OringFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OringFilter.cc' object='liblivestatus_a-OringFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OringFilter.o `test -f 'OringFilter.cc' || echo '$(srcdir)/'`OringFilter.cc + +liblivestatus_a-OringFilter.obj: OringFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OringFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OringFilter.Tpo -c -o liblivestatus_a-OringFilter.obj `if test -f 'OringFilter.cc'; then $(CYGPATH_W) 'OringFilter.cc'; else $(CYGPATH_W) '$(srcdir)/OringFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OringFilter.Tpo $(DEPDIR)/liblivestatus_a-OringFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OringFilter.cc' object='liblivestatus_a-OringFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OringFilter.obj `if test -f 'OringFilter.cc'; then $(CYGPATH_W) 'OringFilter.cc'; else $(CYGPATH_W) '$(srcdir)/OringFilter.cc'; fi` + +liblivestatus_a-OutputBuffer.o: OutputBuffer.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OutputBuffer.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-OutputBuffer.Tpo -c -o liblivestatus_a-OutputBuffer.o `test -f 'OutputBuffer.cc' || echo '$(srcdir)/'`OutputBuffer.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OutputBuffer.Tpo $(DEPDIR)/liblivestatus_a-OutputBuffer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OutputBuffer.cc' object='liblivestatus_a-OutputBuffer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OutputBuffer.o `test -f 'OutputBuffer.cc' || echo '$(srcdir)/'`OutputBuffer.cc + +liblivestatus_a-OutputBuffer.obj: OutputBuffer.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-OutputBuffer.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-OutputBuffer.Tpo -c -o liblivestatus_a-OutputBuffer.obj `if test -f 'OutputBuffer.cc'; then $(CYGPATH_W) 'OutputBuffer.cc'; else $(CYGPATH_W) '$(srcdir)/OutputBuffer.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-OutputBuffer.Tpo $(DEPDIR)/liblivestatus_a-OutputBuffer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='OutputBuffer.cc' object='liblivestatus_a-OutputBuffer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-OutputBuffer.obj `if test -f 'OutputBuffer.cc'; then $(CYGPATH_W) 'OutputBuffer.cc'; else $(CYGPATH_W) '$(srcdir)/OutputBuffer.cc'; fi` + +liblivestatus_a-PerfdataAggregator.o: PerfdataAggregator.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-PerfdataAggregator.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-PerfdataAggregator.Tpo -c -o liblivestatus_a-PerfdataAggregator.o `test -f 'PerfdataAggregator.cc' || echo '$(srcdir)/'`PerfdataAggregator.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-PerfdataAggregator.Tpo $(DEPDIR)/liblivestatus_a-PerfdataAggregator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PerfdataAggregator.cc' object='liblivestatus_a-PerfdataAggregator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-PerfdataAggregator.o `test -f 'PerfdataAggregator.cc' || echo '$(srcdir)/'`PerfdataAggregator.cc + +liblivestatus_a-PerfdataAggregator.obj: PerfdataAggregator.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-PerfdataAggregator.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-PerfdataAggregator.Tpo -c -o liblivestatus_a-PerfdataAggregator.obj `if test -f 'PerfdataAggregator.cc'; then $(CYGPATH_W) 'PerfdataAggregator.cc'; else $(CYGPATH_W) '$(srcdir)/PerfdataAggregator.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-PerfdataAggregator.Tpo $(DEPDIR)/liblivestatus_a-PerfdataAggregator.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='PerfdataAggregator.cc' object='liblivestatus_a-PerfdataAggregator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-PerfdataAggregator.obj `if test -f 'PerfdataAggregator.cc'; then $(CYGPATH_W) 'PerfdataAggregator.cc'; else $(CYGPATH_W) '$(srcdir)/PerfdataAggregator.cc'; fi` + +liblivestatus_a-Query.o: Query.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Query.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Query.Tpo -c -o liblivestatus_a-Query.o `test -f 'Query.cc' || echo '$(srcdir)/'`Query.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Query.Tpo $(DEPDIR)/liblivestatus_a-Query.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Query.cc' object='liblivestatus_a-Query.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Query.o `test -f 'Query.cc' || echo '$(srcdir)/'`Query.cc + +liblivestatus_a-Query.obj: Query.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Query.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Query.Tpo -c -o liblivestatus_a-Query.obj `if test -f 'Query.cc'; then $(CYGPATH_W) 'Query.cc'; else $(CYGPATH_W) '$(srcdir)/Query.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Query.Tpo $(DEPDIR)/liblivestatus_a-Query.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Query.cc' object='liblivestatus_a-Query.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Query.obj `if test -f 'Query.cc'; then $(CYGPATH_W) 'Query.cc'; else $(CYGPATH_W) '$(srcdir)/Query.cc'; fi` + +liblivestatus_a-RegExp.o: RegExp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RegExp.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-RegExp.Tpo -c -o liblivestatus_a-RegExp.o `test -f 'RegExp.cc' || echo '$(srcdir)/'`RegExp.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RegExp.Tpo $(DEPDIR)/liblivestatus_a-RegExp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RegExp.cc' object='liblivestatus_a-RegExp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RegExp.o `test -f 'RegExp.cc' || echo '$(srcdir)/'`RegExp.cc + +liblivestatus_a-RegExp.obj: RegExp.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RegExp.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-RegExp.Tpo -c -o liblivestatus_a-RegExp.obj `if test -f 'RegExp.cc'; then $(CYGPATH_W) 'RegExp.cc'; else $(CYGPATH_W) '$(srcdir)/RegExp.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RegExp.Tpo $(DEPDIR)/liblivestatus_a-RegExp.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RegExp.cc' object='liblivestatus_a-RegExp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RegExp.obj `if test -f 'RegExp.cc'; then $(CYGPATH_W) 'RegExp.cc'; else $(CYGPATH_W) '$(srcdir)/RegExp.cc'; fi` + +liblivestatus_a-Renderer.o: Renderer.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Renderer.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Renderer.Tpo -c -o liblivestatus_a-Renderer.o `test -f 'Renderer.cc' || echo '$(srcdir)/'`Renderer.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Renderer.Tpo $(DEPDIR)/liblivestatus_a-Renderer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Renderer.cc' object='liblivestatus_a-Renderer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Renderer.o `test -f 'Renderer.cc' || echo '$(srcdir)/'`Renderer.cc + +liblivestatus_a-Renderer.obj: Renderer.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Renderer.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Renderer.Tpo -c -o liblivestatus_a-Renderer.obj `if test -f 'Renderer.cc'; then $(CYGPATH_W) 'Renderer.cc'; else $(CYGPATH_W) '$(srcdir)/Renderer.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Renderer.Tpo $(DEPDIR)/liblivestatus_a-Renderer.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Renderer.cc' object='liblivestatus_a-Renderer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Renderer.obj `if test -f 'Renderer.cc'; then $(CYGPATH_W) 'Renderer.cc'; else $(CYGPATH_W) '$(srcdir)/Renderer.cc'; fi` + +liblivestatus_a-RendererBrokenCSV.o: RendererBrokenCSV.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererBrokenCSV.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererBrokenCSV.Tpo -c -o liblivestatus_a-RendererBrokenCSV.o `test -f 'RendererBrokenCSV.cc' || echo '$(srcdir)/'`RendererBrokenCSV.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererBrokenCSV.Tpo $(DEPDIR)/liblivestatus_a-RendererBrokenCSV.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererBrokenCSV.cc' object='liblivestatus_a-RendererBrokenCSV.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererBrokenCSV.o `test -f 'RendererBrokenCSV.cc' || echo '$(srcdir)/'`RendererBrokenCSV.cc + +liblivestatus_a-RendererBrokenCSV.obj: RendererBrokenCSV.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererBrokenCSV.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererBrokenCSV.Tpo -c -o liblivestatus_a-RendererBrokenCSV.obj `if test -f 'RendererBrokenCSV.cc'; then $(CYGPATH_W) 'RendererBrokenCSV.cc'; else $(CYGPATH_W) '$(srcdir)/RendererBrokenCSV.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererBrokenCSV.Tpo $(DEPDIR)/liblivestatus_a-RendererBrokenCSV.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererBrokenCSV.cc' object='liblivestatus_a-RendererBrokenCSV.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererBrokenCSV.obj `if test -f 'RendererBrokenCSV.cc'; then $(CYGPATH_W) 'RendererBrokenCSV.cc'; else $(CYGPATH_W) '$(srcdir)/RendererBrokenCSV.cc'; fi` + +liblivestatus_a-RendererCSV.o: RendererCSV.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererCSV.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererCSV.Tpo -c -o liblivestatus_a-RendererCSV.o `test -f 'RendererCSV.cc' || echo '$(srcdir)/'`RendererCSV.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererCSV.Tpo $(DEPDIR)/liblivestatus_a-RendererCSV.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererCSV.cc' object='liblivestatus_a-RendererCSV.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererCSV.o `test -f 'RendererCSV.cc' || echo '$(srcdir)/'`RendererCSV.cc + +liblivestatus_a-RendererCSV.obj: RendererCSV.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererCSV.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererCSV.Tpo -c -o liblivestatus_a-RendererCSV.obj `if test -f 'RendererCSV.cc'; then $(CYGPATH_W) 'RendererCSV.cc'; else $(CYGPATH_W) '$(srcdir)/RendererCSV.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererCSV.Tpo $(DEPDIR)/liblivestatus_a-RendererCSV.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererCSV.cc' object='liblivestatus_a-RendererCSV.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererCSV.obj `if test -f 'RendererCSV.cc'; then $(CYGPATH_W) 'RendererCSV.cc'; else $(CYGPATH_W) '$(srcdir)/RendererCSV.cc'; fi` + +liblivestatus_a-RendererJSON.o: RendererJSON.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererJSON.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererJSON.Tpo -c -o liblivestatus_a-RendererJSON.o `test -f 'RendererJSON.cc' || echo '$(srcdir)/'`RendererJSON.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererJSON.Tpo $(DEPDIR)/liblivestatus_a-RendererJSON.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererJSON.cc' object='liblivestatus_a-RendererJSON.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererJSON.o `test -f 'RendererJSON.cc' || echo '$(srcdir)/'`RendererJSON.cc + +liblivestatus_a-RendererJSON.obj: RendererJSON.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererJSON.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererJSON.Tpo -c -o liblivestatus_a-RendererJSON.obj `if test -f 'RendererJSON.cc'; then $(CYGPATH_W) 'RendererJSON.cc'; else $(CYGPATH_W) '$(srcdir)/RendererJSON.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererJSON.Tpo $(DEPDIR)/liblivestatus_a-RendererJSON.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererJSON.cc' object='liblivestatus_a-RendererJSON.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererJSON.obj `if test -f 'RendererJSON.cc'; then $(CYGPATH_W) 'RendererJSON.cc'; else $(CYGPATH_W) '$(srcdir)/RendererJSON.cc'; fi` + +liblivestatus_a-RendererPython.o: RendererPython.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererPython.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererPython.Tpo -c -o liblivestatus_a-RendererPython.o `test -f 'RendererPython.cc' || echo '$(srcdir)/'`RendererPython.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererPython.Tpo $(DEPDIR)/liblivestatus_a-RendererPython.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererPython.cc' object='liblivestatus_a-RendererPython.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererPython.o `test -f 'RendererPython.cc' || echo '$(srcdir)/'`RendererPython.cc + +liblivestatus_a-RendererPython.obj: RendererPython.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererPython.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererPython.Tpo -c -o liblivestatus_a-RendererPython.obj `if test -f 'RendererPython.cc'; then $(CYGPATH_W) 'RendererPython.cc'; else $(CYGPATH_W) '$(srcdir)/RendererPython.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererPython.Tpo $(DEPDIR)/liblivestatus_a-RendererPython.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererPython.cc' object='liblivestatus_a-RendererPython.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererPython.obj `if test -f 'RendererPython.cc'; then $(CYGPATH_W) 'RendererPython.cc'; else $(CYGPATH_W) '$(srcdir)/RendererPython.cc'; fi` + +liblivestatus_a-RendererPython3.o: RendererPython3.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererPython3.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererPython3.Tpo -c -o liblivestatus_a-RendererPython3.o `test -f 'RendererPython3.cc' || echo '$(srcdir)/'`RendererPython3.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererPython3.Tpo $(DEPDIR)/liblivestatus_a-RendererPython3.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererPython3.cc' object='liblivestatus_a-RendererPython3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererPython3.o `test -f 'RendererPython3.cc' || echo '$(srcdir)/'`RendererPython3.cc + +liblivestatus_a-RendererPython3.obj: RendererPython3.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-RendererPython3.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-RendererPython3.Tpo -c -o liblivestatus_a-RendererPython3.obj `if test -f 'RendererPython3.cc'; then $(CYGPATH_W) 'RendererPython3.cc'; else $(CYGPATH_W) '$(srcdir)/RendererPython3.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-RendererPython3.Tpo $(DEPDIR)/liblivestatus_a-RendererPython3.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='RendererPython3.cc' object='liblivestatus_a-RendererPython3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-RendererPython3.obj `if test -f 'RendererPython3.cc'; then $(CYGPATH_W) 'RendererPython3.cc'; else $(CYGPATH_W) '$(srcdir)/RendererPython3.cc'; fi` + +liblivestatus_a-ServiceContactsColumn.o: ServiceContactsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceContactsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceContactsColumn.Tpo -c -o liblivestatus_a-ServiceContactsColumn.o `test -f 'ServiceContactsColumn.cc' || echo '$(srcdir)/'`ServiceContactsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceContactsColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceContactsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceContactsColumn.cc' object='liblivestatus_a-ServiceContactsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceContactsColumn.o `test -f 'ServiceContactsColumn.cc' || echo '$(srcdir)/'`ServiceContactsColumn.cc + +liblivestatus_a-ServiceContactsColumn.obj: ServiceContactsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceContactsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceContactsColumn.Tpo -c -o liblivestatus_a-ServiceContactsColumn.obj `if test -f 'ServiceContactsColumn.cc'; then $(CYGPATH_W) 'ServiceContactsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceContactsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceContactsColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceContactsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceContactsColumn.cc' object='liblivestatus_a-ServiceContactsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceContactsColumn.obj `if test -f 'ServiceContactsColumn.cc'; then $(CYGPATH_W) 'ServiceContactsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceContactsColumn.cc'; fi` + +liblivestatus_a-ServiceGroupMembersColumn.o: ServiceGroupMembersColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceGroupMembersColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceGroupMembersColumn.Tpo -c -o liblivestatus_a-ServiceGroupMembersColumn.o `test -f 'ServiceGroupMembersColumn.cc' || echo '$(srcdir)/'`ServiceGroupMembersColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceGroupMembersColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceGroupMembersColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceGroupMembersColumn.cc' object='liblivestatus_a-ServiceGroupMembersColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceGroupMembersColumn.o `test -f 'ServiceGroupMembersColumn.cc' || echo '$(srcdir)/'`ServiceGroupMembersColumn.cc + +liblivestatus_a-ServiceGroupMembersColumn.obj: ServiceGroupMembersColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceGroupMembersColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceGroupMembersColumn.Tpo -c -o liblivestatus_a-ServiceGroupMembersColumn.obj `if test -f 'ServiceGroupMembersColumn.cc'; then $(CYGPATH_W) 'ServiceGroupMembersColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceGroupMembersColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceGroupMembersColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceGroupMembersColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceGroupMembersColumn.cc' object='liblivestatus_a-ServiceGroupMembersColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceGroupMembersColumn.obj `if test -f 'ServiceGroupMembersColumn.cc'; then $(CYGPATH_W) 'ServiceGroupMembersColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceGroupMembersColumn.cc'; fi` + +liblivestatus_a-ServiceGroupsColumn.o: ServiceGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceGroupsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceGroupsColumn.Tpo -c -o liblivestatus_a-ServiceGroupsColumn.o `test -f 'ServiceGroupsColumn.cc' || echo '$(srcdir)/'`ServiceGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceGroupsColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceGroupsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceGroupsColumn.cc' object='liblivestatus_a-ServiceGroupsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceGroupsColumn.o `test -f 'ServiceGroupsColumn.cc' || echo '$(srcdir)/'`ServiceGroupsColumn.cc + +liblivestatus_a-ServiceGroupsColumn.obj: ServiceGroupsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceGroupsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceGroupsColumn.Tpo -c -o liblivestatus_a-ServiceGroupsColumn.obj `if test -f 'ServiceGroupsColumn.cc'; then $(CYGPATH_W) 'ServiceGroupsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceGroupsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceGroupsColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceGroupsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceGroupsColumn.cc' object='liblivestatus_a-ServiceGroupsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceGroupsColumn.obj `if test -f 'ServiceGroupsColumn.cc'; then $(CYGPATH_W) 'ServiceGroupsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceGroupsColumn.cc'; fi` + +liblivestatus_a-ServiceListColumn.o: ServiceListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceListColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceListColumn.Tpo -c -o liblivestatus_a-ServiceListColumn.o `test -f 'ServiceListColumn.cc' || echo '$(srcdir)/'`ServiceListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceListColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceListColumn.cc' object='liblivestatus_a-ServiceListColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceListColumn.o `test -f 'ServiceListColumn.cc' || echo '$(srcdir)/'`ServiceListColumn.cc + +liblivestatus_a-ServiceListColumn.obj: ServiceListColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceListColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceListColumn.Tpo -c -o liblivestatus_a-ServiceListColumn.obj `if test -f 'ServiceListColumn.cc'; then $(CYGPATH_W) 'ServiceListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceListColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceListColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceListColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceListColumn.cc' object='liblivestatus_a-ServiceListColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceListColumn.obj `if test -f 'ServiceListColumn.cc'; then $(CYGPATH_W) 'ServiceListColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceListColumn.cc'; fi` + +liblivestatus_a-ServiceListStateColumn.o: ServiceListStateColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceListStateColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceListStateColumn.Tpo -c -o liblivestatus_a-ServiceListStateColumn.o `test -f 'ServiceListStateColumn.cc' || echo '$(srcdir)/'`ServiceListStateColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceListStateColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceListStateColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceListStateColumn.cc' object='liblivestatus_a-ServiceListStateColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceListStateColumn.o `test -f 'ServiceListStateColumn.cc' || echo '$(srcdir)/'`ServiceListStateColumn.cc + +liblivestatus_a-ServiceListStateColumn.obj: ServiceListStateColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceListStateColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceListStateColumn.Tpo -c -o liblivestatus_a-ServiceListStateColumn.obj `if test -f 'ServiceListStateColumn.cc'; then $(CYGPATH_W) 'ServiceListStateColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceListStateColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceListStateColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceListStateColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceListStateColumn.cc' object='liblivestatus_a-ServiceListStateColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceListStateColumn.obj `if test -f 'ServiceListStateColumn.cc'; then $(CYGPATH_W) 'ServiceListStateColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceListStateColumn.cc'; fi` + +liblivestatus_a-ServiceSpecialDoubleColumn.o: ServiceSpecialDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceSpecialDoubleColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceSpecialDoubleColumn.Tpo -c -o liblivestatus_a-ServiceSpecialDoubleColumn.o `test -f 'ServiceSpecialDoubleColumn.cc' || echo '$(srcdir)/'`ServiceSpecialDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceSpecialDoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceSpecialDoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceSpecialDoubleColumn.cc' object='liblivestatus_a-ServiceSpecialDoubleColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceSpecialDoubleColumn.o `test -f 'ServiceSpecialDoubleColumn.cc' || echo '$(srcdir)/'`ServiceSpecialDoubleColumn.cc + +liblivestatus_a-ServiceSpecialDoubleColumn.obj: ServiceSpecialDoubleColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceSpecialDoubleColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceSpecialDoubleColumn.Tpo -c -o liblivestatus_a-ServiceSpecialDoubleColumn.obj `if test -f 'ServiceSpecialDoubleColumn.cc'; then $(CYGPATH_W) 'ServiceSpecialDoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceSpecialDoubleColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceSpecialDoubleColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceSpecialDoubleColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceSpecialDoubleColumn.cc' object='liblivestatus_a-ServiceSpecialDoubleColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceSpecialDoubleColumn.obj `if test -f 'ServiceSpecialDoubleColumn.cc'; then $(CYGPATH_W) 'ServiceSpecialDoubleColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceSpecialDoubleColumn.cc'; fi` + +liblivestatus_a-ServiceSpecialIntColumn.o: ServiceSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceSpecialIntColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceSpecialIntColumn.Tpo -c -o liblivestatus_a-ServiceSpecialIntColumn.o `test -f 'ServiceSpecialIntColumn.cc' || echo '$(srcdir)/'`ServiceSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceSpecialIntColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceSpecialIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceSpecialIntColumn.cc' object='liblivestatus_a-ServiceSpecialIntColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceSpecialIntColumn.o `test -f 'ServiceSpecialIntColumn.cc' || echo '$(srcdir)/'`ServiceSpecialIntColumn.cc + +liblivestatus_a-ServiceSpecialIntColumn.obj: ServiceSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-ServiceSpecialIntColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-ServiceSpecialIntColumn.Tpo -c -o liblivestatus_a-ServiceSpecialIntColumn.obj `if test -f 'ServiceSpecialIntColumn.cc'; then $(CYGPATH_W) 'ServiceSpecialIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceSpecialIntColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-ServiceSpecialIntColumn.Tpo $(DEPDIR)/liblivestatus_a-ServiceSpecialIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ServiceSpecialIntColumn.cc' object='liblivestatus_a-ServiceSpecialIntColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-ServiceSpecialIntColumn.obj `if test -f 'ServiceSpecialIntColumn.cc'; then $(CYGPATH_W) 'ServiceSpecialIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/ServiceSpecialIntColumn.cc'; fi` + +liblivestatus_a-StatsColumn.o: StatsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StatsColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-StatsColumn.Tpo -c -o liblivestatus_a-StatsColumn.o `test -f 'StatsColumn.cc' || echo '$(srcdir)/'`StatsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StatsColumn.Tpo $(DEPDIR)/liblivestatus_a-StatsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StatsColumn.cc' object='liblivestatus_a-StatsColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StatsColumn.o `test -f 'StatsColumn.cc' || echo '$(srcdir)/'`StatsColumn.cc + +liblivestatus_a-StatsColumn.obj: StatsColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StatsColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-StatsColumn.Tpo -c -o liblivestatus_a-StatsColumn.obj `if test -f 'StatsColumn.cc'; then $(CYGPATH_W) 'StatsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/StatsColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StatsColumn.Tpo $(DEPDIR)/liblivestatus_a-StatsColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StatsColumn.cc' object='liblivestatus_a-StatsColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StatsColumn.obj `if test -f 'StatsColumn.cc'; then $(CYGPATH_W) 'StatsColumn.cc'; else $(CYGPATH_W) '$(srcdir)/StatsColumn.cc'; fi` + +liblivestatus_a-StatusSpecialIntColumn.o: StatusSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StatusSpecialIntColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-StatusSpecialIntColumn.Tpo -c -o liblivestatus_a-StatusSpecialIntColumn.o `test -f 'StatusSpecialIntColumn.cc' || echo '$(srcdir)/'`StatusSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StatusSpecialIntColumn.Tpo $(DEPDIR)/liblivestatus_a-StatusSpecialIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StatusSpecialIntColumn.cc' object='liblivestatus_a-StatusSpecialIntColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StatusSpecialIntColumn.o `test -f 'StatusSpecialIntColumn.cc' || echo '$(srcdir)/'`StatusSpecialIntColumn.cc + +liblivestatus_a-StatusSpecialIntColumn.obj: StatusSpecialIntColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StatusSpecialIntColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-StatusSpecialIntColumn.Tpo -c -o liblivestatus_a-StatusSpecialIntColumn.obj `if test -f 'StatusSpecialIntColumn.cc'; then $(CYGPATH_W) 'StatusSpecialIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/StatusSpecialIntColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StatusSpecialIntColumn.Tpo $(DEPDIR)/liblivestatus_a-StatusSpecialIntColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StatusSpecialIntColumn.cc' object='liblivestatus_a-StatusSpecialIntColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StatusSpecialIntColumn.obj `if test -f 'StatusSpecialIntColumn.cc'; then $(CYGPATH_W) 'StatusSpecialIntColumn.cc'; else $(CYGPATH_W) '$(srcdir)/StatusSpecialIntColumn.cc'; fi` + +liblivestatus_a-Store.o: Store.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Store.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Store.Tpo -c -o liblivestatus_a-Store.o `test -f 'Store.cc' || echo '$(srcdir)/'`Store.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Store.Tpo $(DEPDIR)/liblivestatus_a-Store.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Store.cc' object='liblivestatus_a-Store.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Store.o `test -f 'Store.cc' || echo '$(srcdir)/'`Store.cc + +liblivestatus_a-Store.obj: Store.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Store.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Store.Tpo -c -o liblivestatus_a-Store.obj `if test -f 'Store.cc'; then $(CYGPATH_W) 'Store.cc'; else $(CYGPATH_W) '$(srcdir)/Store.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Store.Tpo $(DEPDIR)/liblivestatus_a-Store.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Store.cc' object='liblivestatus_a-Store.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Store.obj `if test -f 'Store.cc'; then $(CYGPATH_W) 'Store.cc'; else $(CYGPATH_W) '$(srcdir)/Store.cc'; fi` + +liblivestatus_a-StringColumn.o: StringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StringColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-StringColumn.Tpo -c -o liblivestatus_a-StringColumn.o `test -f 'StringColumn.cc' || echo '$(srcdir)/'`StringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StringColumn.Tpo $(DEPDIR)/liblivestatus_a-StringColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StringColumn.cc' object='liblivestatus_a-StringColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StringColumn.o `test -f 'StringColumn.cc' || echo '$(srcdir)/'`StringColumn.cc + +liblivestatus_a-StringColumn.obj: StringColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StringColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-StringColumn.Tpo -c -o liblivestatus_a-StringColumn.obj `if test -f 'StringColumn.cc'; then $(CYGPATH_W) 'StringColumn.cc'; else $(CYGPATH_W) '$(srcdir)/StringColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StringColumn.Tpo $(DEPDIR)/liblivestatus_a-StringColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StringColumn.cc' object='liblivestatus_a-StringColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StringColumn.obj `if test -f 'StringColumn.cc'; then $(CYGPATH_W) 'StringColumn.cc'; else $(CYGPATH_W) '$(srcdir)/StringColumn.cc'; fi` + +liblivestatus_a-StringFilter.o: StringFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StringFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-StringFilter.Tpo -c -o liblivestatus_a-StringFilter.o `test -f 'StringFilter.cc' || echo '$(srcdir)/'`StringFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StringFilter.Tpo $(DEPDIR)/liblivestatus_a-StringFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StringFilter.cc' object='liblivestatus_a-StringFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StringFilter.o `test -f 'StringFilter.cc' || echo '$(srcdir)/'`StringFilter.cc + +liblivestatus_a-StringFilter.obj: StringFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StringFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-StringFilter.Tpo -c -o liblivestatus_a-StringFilter.obj `if test -f 'StringFilter.cc'; then $(CYGPATH_W) 'StringFilter.cc'; else $(CYGPATH_W) '$(srcdir)/StringFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StringFilter.Tpo $(DEPDIR)/liblivestatus_a-StringFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StringFilter.cc' object='liblivestatus_a-StringFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StringFilter.obj `if test -f 'StringFilter.cc'; then $(CYGPATH_W) 'StringFilter.cc'; else $(CYGPATH_W) '$(srcdir)/StringFilter.cc'; fi` + +liblivestatus_a-StringUtils.o: StringUtils.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StringUtils.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-StringUtils.Tpo -c -o liblivestatus_a-StringUtils.o `test -f 'StringUtils.cc' || echo '$(srcdir)/'`StringUtils.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StringUtils.Tpo $(DEPDIR)/liblivestatus_a-StringUtils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StringUtils.cc' object='liblivestatus_a-StringUtils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StringUtils.o `test -f 'StringUtils.cc' || echo '$(srcdir)/'`StringUtils.cc + +liblivestatus_a-StringUtils.obj: StringUtils.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-StringUtils.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-StringUtils.Tpo -c -o liblivestatus_a-StringUtils.obj `if test -f 'StringUtils.cc'; then $(CYGPATH_W) 'StringUtils.cc'; else $(CYGPATH_W) '$(srcdir)/StringUtils.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-StringUtils.Tpo $(DEPDIR)/liblivestatus_a-StringUtils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='StringUtils.cc' object='liblivestatus_a-StringUtils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-StringUtils.obj `if test -f 'StringUtils.cc'; then $(CYGPATH_W) 'StringUtils.cc'; else $(CYGPATH_W) '$(srcdir)/StringUtils.cc'; fi` + +liblivestatus_a-Table.o: Table.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Table.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Table.Tpo -c -o liblivestatus_a-Table.o `test -f 'Table.cc' || echo '$(srcdir)/'`Table.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Table.Tpo $(DEPDIR)/liblivestatus_a-Table.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Table.cc' object='liblivestatus_a-Table.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Table.o `test -f 'Table.cc' || echo '$(srcdir)/'`Table.cc + +liblivestatus_a-Table.obj: Table.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Table.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Table.Tpo -c -o liblivestatus_a-Table.obj `if test -f 'Table.cc'; then $(CYGPATH_W) 'Table.cc'; else $(CYGPATH_W) '$(srcdir)/Table.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Table.Tpo $(DEPDIR)/liblivestatus_a-Table.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Table.cc' object='liblivestatus_a-Table.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Table.obj `if test -f 'Table.cc'; then $(CYGPATH_W) 'Table.cc'; else $(CYGPATH_W) '$(srcdir)/Table.cc'; fi` + +liblivestatus_a-TableColumns.o: TableColumns.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableColumns.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableColumns.Tpo -c -o liblivestatus_a-TableColumns.o `test -f 'TableColumns.cc' || echo '$(srcdir)/'`TableColumns.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableColumns.Tpo $(DEPDIR)/liblivestatus_a-TableColumns.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableColumns.cc' object='liblivestatus_a-TableColumns.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableColumns.o `test -f 'TableColumns.cc' || echo '$(srcdir)/'`TableColumns.cc + +liblivestatus_a-TableColumns.obj: TableColumns.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableColumns.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableColumns.Tpo -c -o liblivestatus_a-TableColumns.obj `if test -f 'TableColumns.cc'; then $(CYGPATH_W) 'TableColumns.cc'; else $(CYGPATH_W) '$(srcdir)/TableColumns.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableColumns.Tpo $(DEPDIR)/liblivestatus_a-TableColumns.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableColumns.cc' object='liblivestatus_a-TableColumns.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableColumns.obj `if test -f 'TableColumns.cc'; then $(CYGPATH_W) 'TableColumns.cc'; else $(CYGPATH_W) '$(srcdir)/TableColumns.cc'; fi` + +liblivestatus_a-TableCommands.o: TableCommands.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableCommands.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableCommands.Tpo -c -o liblivestatus_a-TableCommands.o `test -f 'TableCommands.cc' || echo '$(srcdir)/'`TableCommands.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableCommands.Tpo $(DEPDIR)/liblivestatus_a-TableCommands.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableCommands.cc' object='liblivestatus_a-TableCommands.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableCommands.o `test -f 'TableCommands.cc' || echo '$(srcdir)/'`TableCommands.cc + +liblivestatus_a-TableCommands.obj: TableCommands.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableCommands.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableCommands.Tpo -c -o liblivestatus_a-TableCommands.obj `if test -f 'TableCommands.cc'; then $(CYGPATH_W) 'TableCommands.cc'; else $(CYGPATH_W) '$(srcdir)/TableCommands.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableCommands.Tpo $(DEPDIR)/liblivestatus_a-TableCommands.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableCommands.cc' object='liblivestatus_a-TableCommands.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableCommands.obj `if test -f 'TableCommands.cc'; then $(CYGPATH_W) 'TableCommands.cc'; else $(CYGPATH_W) '$(srcdir)/TableCommands.cc'; fi` + +liblivestatus_a-TableComments.o: TableComments.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableComments.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableComments.Tpo -c -o liblivestatus_a-TableComments.o `test -f 'TableComments.cc' || echo '$(srcdir)/'`TableComments.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableComments.Tpo $(DEPDIR)/liblivestatus_a-TableComments.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableComments.cc' object='liblivestatus_a-TableComments.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableComments.o `test -f 'TableComments.cc' || echo '$(srcdir)/'`TableComments.cc + +liblivestatus_a-TableComments.obj: TableComments.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableComments.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableComments.Tpo -c -o liblivestatus_a-TableComments.obj `if test -f 'TableComments.cc'; then $(CYGPATH_W) 'TableComments.cc'; else $(CYGPATH_W) '$(srcdir)/TableComments.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableComments.Tpo $(DEPDIR)/liblivestatus_a-TableComments.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableComments.cc' object='liblivestatus_a-TableComments.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableComments.obj `if test -f 'TableComments.cc'; then $(CYGPATH_W) 'TableComments.cc'; else $(CYGPATH_W) '$(srcdir)/TableComments.cc'; fi` + +liblivestatus_a-TableContactGroups.o: TableContactGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableContactGroups.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableContactGroups.Tpo -c -o liblivestatus_a-TableContactGroups.o `test -f 'TableContactGroups.cc' || echo '$(srcdir)/'`TableContactGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableContactGroups.Tpo $(DEPDIR)/liblivestatus_a-TableContactGroups.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableContactGroups.cc' object='liblivestatus_a-TableContactGroups.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableContactGroups.o `test -f 'TableContactGroups.cc' || echo '$(srcdir)/'`TableContactGroups.cc + +liblivestatus_a-TableContactGroups.obj: TableContactGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableContactGroups.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableContactGroups.Tpo -c -o liblivestatus_a-TableContactGroups.obj `if test -f 'TableContactGroups.cc'; then $(CYGPATH_W) 'TableContactGroups.cc'; else $(CYGPATH_W) '$(srcdir)/TableContactGroups.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableContactGroups.Tpo $(DEPDIR)/liblivestatus_a-TableContactGroups.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableContactGroups.cc' object='liblivestatus_a-TableContactGroups.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableContactGroups.obj `if test -f 'TableContactGroups.cc'; then $(CYGPATH_W) 'TableContactGroups.cc'; else $(CYGPATH_W) '$(srcdir)/TableContactGroups.cc'; fi` + +liblivestatus_a-TableContacts.o: TableContacts.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableContacts.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableContacts.Tpo -c -o liblivestatus_a-TableContacts.o `test -f 'TableContacts.cc' || echo '$(srcdir)/'`TableContacts.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableContacts.Tpo $(DEPDIR)/liblivestatus_a-TableContacts.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableContacts.cc' object='liblivestatus_a-TableContacts.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableContacts.o `test -f 'TableContacts.cc' || echo '$(srcdir)/'`TableContacts.cc + +liblivestatus_a-TableContacts.obj: TableContacts.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableContacts.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableContacts.Tpo -c -o liblivestatus_a-TableContacts.obj `if test -f 'TableContacts.cc'; then $(CYGPATH_W) 'TableContacts.cc'; else $(CYGPATH_W) '$(srcdir)/TableContacts.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableContacts.Tpo $(DEPDIR)/liblivestatus_a-TableContacts.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableContacts.cc' object='liblivestatus_a-TableContacts.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableContacts.obj `if test -f 'TableContacts.cc'; then $(CYGPATH_W) 'TableContacts.cc'; else $(CYGPATH_W) '$(srcdir)/TableContacts.cc'; fi` + +liblivestatus_a-TableDowntimes.o: TableDowntimes.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableDowntimes.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableDowntimes.Tpo -c -o liblivestatus_a-TableDowntimes.o `test -f 'TableDowntimes.cc' || echo '$(srcdir)/'`TableDowntimes.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableDowntimes.Tpo $(DEPDIR)/liblivestatus_a-TableDowntimes.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableDowntimes.cc' object='liblivestatus_a-TableDowntimes.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableDowntimes.o `test -f 'TableDowntimes.cc' || echo '$(srcdir)/'`TableDowntimes.cc + +liblivestatus_a-TableDowntimes.obj: TableDowntimes.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableDowntimes.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableDowntimes.Tpo -c -o liblivestatus_a-TableDowntimes.obj `if test -f 'TableDowntimes.cc'; then $(CYGPATH_W) 'TableDowntimes.cc'; else $(CYGPATH_W) '$(srcdir)/TableDowntimes.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableDowntimes.Tpo $(DEPDIR)/liblivestatus_a-TableDowntimes.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableDowntimes.cc' object='liblivestatus_a-TableDowntimes.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableDowntimes.obj `if test -f 'TableDowntimes.cc'; then $(CYGPATH_W) 'TableDowntimes.cc'; else $(CYGPATH_W) '$(srcdir)/TableDowntimes.cc'; fi` + +liblivestatus_a-TableEventConsole.o: TableEventConsole.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsole.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsole.Tpo -c -o liblivestatus_a-TableEventConsole.o `test -f 'TableEventConsole.cc' || echo '$(srcdir)/'`TableEventConsole.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsole.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsole.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsole.cc' object='liblivestatus_a-TableEventConsole.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsole.o `test -f 'TableEventConsole.cc' || echo '$(srcdir)/'`TableEventConsole.cc + +liblivestatus_a-TableEventConsole.obj: TableEventConsole.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsole.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsole.Tpo -c -o liblivestatus_a-TableEventConsole.obj `if test -f 'TableEventConsole.cc'; then $(CYGPATH_W) 'TableEventConsole.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsole.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsole.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsole.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsole.cc' object='liblivestatus_a-TableEventConsole.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsole.obj `if test -f 'TableEventConsole.cc'; then $(CYGPATH_W) 'TableEventConsole.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsole.cc'; fi` + +liblivestatus_a-TableEventConsoleEvents.o: TableEventConsoleEvents.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleEvents.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleEvents.Tpo -c -o liblivestatus_a-TableEventConsoleEvents.o `test -f 'TableEventConsoleEvents.cc' || echo '$(srcdir)/'`TableEventConsoleEvents.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleEvents.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleEvents.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleEvents.cc' object='liblivestatus_a-TableEventConsoleEvents.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleEvents.o `test -f 'TableEventConsoleEvents.cc' || echo '$(srcdir)/'`TableEventConsoleEvents.cc + +liblivestatus_a-TableEventConsoleEvents.obj: TableEventConsoleEvents.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleEvents.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleEvents.Tpo -c -o liblivestatus_a-TableEventConsoleEvents.obj `if test -f 'TableEventConsoleEvents.cc'; then $(CYGPATH_W) 'TableEventConsoleEvents.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleEvents.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleEvents.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleEvents.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleEvents.cc' object='liblivestatus_a-TableEventConsoleEvents.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleEvents.obj `if test -f 'TableEventConsoleEvents.cc'; then $(CYGPATH_W) 'TableEventConsoleEvents.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleEvents.cc'; fi` + +liblivestatus_a-TableEventConsoleHistory.o: TableEventConsoleHistory.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleHistory.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleHistory.Tpo -c -o liblivestatus_a-TableEventConsoleHistory.o `test -f 'TableEventConsoleHistory.cc' || echo '$(srcdir)/'`TableEventConsoleHistory.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleHistory.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleHistory.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleHistory.cc' object='liblivestatus_a-TableEventConsoleHistory.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleHistory.o `test -f 'TableEventConsoleHistory.cc' || echo '$(srcdir)/'`TableEventConsoleHistory.cc + +liblivestatus_a-TableEventConsoleHistory.obj: TableEventConsoleHistory.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleHistory.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleHistory.Tpo -c -o liblivestatus_a-TableEventConsoleHistory.obj `if test -f 'TableEventConsoleHistory.cc'; then $(CYGPATH_W) 'TableEventConsoleHistory.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleHistory.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleHistory.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleHistory.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleHistory.cc' object='liblivestatus_a-TableEventConsoleHistory.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleHistory.obj `if test -f 'TableEventConsoleHistory.cc'; then $(CYGPATH_W) 'TableEventConsoleHistory.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleHistory.cc'; fi` + +liblivestatus_a-TableEventConsoleReplication.o: TableEventConsoleReplication.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleReplication.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleReplication.Tpo -c -o liblivestatus_a-TableEventConsoleReplication.o `test -f 'TableEventConsoleReplication.cc' || echo '$(srcdir)/'`TableEventConsoleReplication.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleReplication.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleReplication.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleReplication.cc' object='liblivestatus_a-TableEventConsoleReplication.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleReplication.o `test -f 'TableEventConsoleReplication.cc' || echo '$(srcdir)/'`TableEventConsoleReplication.cc + +liblivestatus_a-TableEventConsoleReplication.obj: TableEventConsoleReplication.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleReplication.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleReplication.Tpo -c -o liblivestatus_a-TableEventConsoleReplication.obj `if test -f 'TableEventConsoleReplication.cc'; then $(CYGPATH_W) 'TableEventConsoleReplication.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleReplication.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleReplication.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleReplication.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleReplication.cc' object='liblivestatus_a-TableEventConsoleReplication.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleReplication.obj `if test -f 'TableEventConsoleReplication.cc'; then $(CYGPATH_W) 'TableEventConsoleReplication.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleReplication.cc'; fi` + +liblivestatus_a-TableEventConsoleRules.o: TableEventConsoleRules.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleRules.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleRules.Tpo -c -o liblivestatus_a-TableEventConsoleRules.o `test -f 'TableEventConsoleRules.cc' || echo '$(srcdir)/'`TableEventConsoleRules.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleRules.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleRules.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleRules.cc' object='liblivestatus_a-TableEventConsoleRules.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleRules.o `test -f 'TableEventConsoleRules.cc' || echo '$(srcdir)/'`TableEventConsoleRules.cc + +liblivestatus_a-TableEventConsoleRules.obj: TableEventConsoleRules.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleRules.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleRules.Tpo -c -o liblivestatus_a-TableEventConsoleRules.obj `if test -f 'TableEventConsoleRules.cc'; then $(CYGPATH_W) 'TableEventConsoleRules.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleRules.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleRules.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleRules.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleRules.cc' object='liblivestatus_a-TableEventConsoleRules.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleRules.obj `if test -f 'TableEventConsoleRules.cc'; then $(CYGPATH_W) 'TableEventConsoleRules.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleRules.cc'; fi` + +liblivestatus_a-TableEventConsoleStatus.o: TableEventConsoleStatus.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleStatus.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleStatus.Tpo -c -o liblivestatus_a-TableEventConsoleStatus.o `test -f 'TableEventConsoleStatus.cc' || echo '$(srcdir)/'`TableEventConsoleStatus.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleStatus.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleStatus.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleStatus.cc' object='liblivestatus_a-TableEventConsoleStatus.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleStatus.o `test -f 'TableEventConsoleStatus.cc' || echo '$(srcdir)/'`TableEventConsoleStatus.cc + +liblivestatus_a-TableEventConsoleStatus.obj: TableEventConsoleStatus.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableEventConsoleStatus.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableEventConsoleStatus.Tpo -c -o liblivestatus_a-TableEventConsoleStatus.obj `if test -f 'TableEventConsoleStatus.cc'; then $(CYGPATH_W) 'TableEventConsoleStatus.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleStatus.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableEventConsoleStatus.Tpo $(DEPDIR)/liblivestatus_a-TableEventConsoleStatus.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableEventConsoleStatus.cc' object='liblivestatus_a-TableEventConsoleStatus.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableEventConsoleStatus.obj `if test -f 'TableEventConsoleStatus.cc'; then $(CYGPATH_W) 'TableEventConsoleStatus.cc'; else $(CYGPATH_W) '$(srcdir)/TableEventConsoleStatus.cc'; fi` + +liblivestatus_a-TableHostGroups.o: TableHostGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableHostGroups.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableHostGroups.Tpo -c -o liblivestatus_a-TableHostGroups.o `test -f 'TableHostGroups.cc' || echo '$(srcdir)/'`TableHostGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableHostGroups.Tpo $(DEPDIR)/liblivestatus_a-TableHostGroups.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableHostGroups.cc' object='liblivestatus_a-TableHostGroups.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableHostGroups.o `test -f 'TableHostGroups.cc' || echo '$(srcdir)/'`TableHostGroups.cc + +liblivestatus_a-TableHostGroups.obj: TableHostGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableHostGroups.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableHostGroups.Tpo -c -o liblivestatus_a-TableHostGroups.obj `if test -f 'TableHostGroups.cc'; then $(CYGPATH_W) 'TableHostGroups.cc'; else $(CYGPATH_W) '$(srcdir)/TableHostGroups.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableHostGroups.Tpo $(DEPDIR)/liblivestatus_a-TableHostGroups.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableHostGroups.cc' object='liblivestatus_a-TableHostGroups.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableHostGroups.obj `if test -f 'TableHostGroups.cc'; then $(CYGPATH_W) 'TableHostGroups.cc'; else $(CYGPATH_W) '$(srcdir)/TableHostGroups.cc'; fi` + +liblivestatus_a-TableHosts.o: TableHosts.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableHosts.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableHosts.Tpo -c -o liblivestatus_a-TableHosts.o `test -f 'TableHosts.cc' || echo '$(srcdir)/'`TableHosts.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableHosts.Tpo $(DEPDIR)/liblivestatus_a-TableHosts.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableHosts.cc' object='liblivestatus_a-TableHosts.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableHosts.o `test -f 'TableHosts.cc' || echo '$(srcdir)/'`TableHosts.cc + +liblivestatus_a-TableHosts.obj: TableHosts.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableHosts.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableHosts.Tpo -c -o liblivestatus_a-TableHosts.obj `if test -f 'TableHosts.cc'; then $(CYGPATH_W) 'TableHosts.cc'; else $(CYGPATH_W) '$(srcdir)/TableHosts.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableHosts.Tpo $(DEPDIR)/liblivestatus_a-TableHosts.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableHosts.cc' object='liblivestatus_a-TableHosts.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableHosts.obj `if test -f 'TableHosts.cc'; then $(CYGPATH_W) 'TableHosts.cc'; else $(CYGPATH_W) '$(srcdir)/TableHosts.cc'; fi` + +liblivestatus_a-TableHostsByGroup.o: TableHostsByGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableHostsByGroup.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableHostsByGroup.Tpo -c -o liblivestatus_a-TableHostsByGroup.o `test -f 'TableHostsByGroup.cc' || echo '$(srcdir)/'`TableHostsByGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableHostsByGroup.Tpo $(DEPDIR)/liblivestatus_a-TableHostsByGroup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableHostsByGroup.cc' object='liblivestatus_a-TableHostsByGroup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableHostsByGroup.o `test -f 'TableHostsByGroup.cc' || echo '$(srcdir)/'`TableHostsByGroup.cc + +liblivestatus_a-TableHostsByGroup.obj: TableHostsByGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableHostsByGroup.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableHostsByGroup.Tpo -c -o liblivestatus_a-TableHostsByGroup.obj `if test -f 'TableHostsByGroup.cc'; then $(CYGPATH_W) 'TableHostsByGroup.cc'; else $(CYGPATH_W) '$(srcdir)/TableHostsByGroup.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableHostsByGroup.Tpo $(DEPDIR)/liblivestatus_a-TableHostsByGroup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableHostsByGroup.cc' object='liblivestatus_a-TableHostsByGroup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableHostsByGroup.obj `if test -f 'TableHostsByGroup.cc'; then $(CYGPATH_W) 'TableHostsByGroup.cc'; else $(CYGPATH_W) '$(srcdir)/TableHostsByGroup.cc'; fi` + +liblivestatus_a-TableLog.o: TableLog.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableLog.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableLog.Tpo -c -o liblivestatus_a-TableLog.o `test -f 'TableLog.cc' || echo '$(srcdir)/'`TableLog.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableLog.Tpo $(DEPDIR)/liblivestatus_a-TableLog.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableLog.cc' object='liblivestatus_a-TableLog.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableLog.o `test -f 'TableLog.cc' || echo '$(srcdir)/'`TableLog.cc + +liblivestatus_a-TableLog.obj: TableLog.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableLog.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableLog.Tpo -c -o liblivestatus_a-TableLog.obj `if test -f 'TableLog.cc'; then $(CYGPATH_W) 'TableLog.cc'; else $(CYGPATH_W) '$(srcdir)/TableLog.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableLog.Tpo $(DEPDIR)/liblivestatus_a-TableLog.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableLog.cc' object='liblivestatus_a-TableLog.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableLog.obj `if test -f 'TableLog.cc'; then $(CYGPATH_W) 'TableLog.cc'; else $(CYGPATH_W) '$(srcdir)/TableLog.cc'; fi` + +liblivestatus_a-TableServiceGroups.o: TableServiceGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServiceGroups.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServiceGroups.Tpo -c -o liblivestatus_a-TableServiceGroups.o `test -f 'TableServiceGroups.cc' || echo '$(srcdir)/'`TableServiceGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServiceGroups.Tpo $(DEPDIR)/liblivestatus_a-TableServiceGroups.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServiceGroups.cc' object='liblivestatus_a-TableServiceGroups.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServiceGroups.o `test -f 'TableServiceGroups.cc' || echo '$(srcdir)/'`TableServiceGroups.cc + +liblivestatus_a-TableServiceGroups.obj: TableServiceGroups.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServiceGroups.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServiceGroups.Tpo -c -o liblivestatus_a-TableServiceGroups.obj `if test -f 'TableServiceGroups.cc'; then $(CYGPATH_W) 'TableServiceGroups.cc'; else $(CYGPATH_W) '$(srcdir)/TableServiceGroups.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServiceGroups.Tpo $(DEPDIR)/liblivestatus_a-TableServiceGroups.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServiceGroups.cc' object='liblivestatus_a-TableServiceGroups.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServiceGroups.obj `if test -f 'TableServiceGroups.cc'; then $(CYGPATH_W) 'TableServiceGroups.cc'; else $(CYGPATH_W) '$(srcdir)/TableServiceGroups.cc'; fi` + +liblivestatus_a-TableServices.o: TableServices.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServices.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServices.Tpo -c -o liblivestatus_a-TableServices.o `test -f 'TableServices.cc' || echo '$(srcdir)/'`TableServices.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServices.Tpo $(DEPDIR)/liblivestatus_a-TableServices.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServices.cc' object='liblivestatus_a-TableServices.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServices.o `test -f 'TableServices.cc' || echo '$(srcdir)/'`TableServices.cc + +liblivestatus_a-TableServices.obj: TableServices.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServices.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServices.Tpo -c -o liblivestatus_a-TableServices.obj `if test -f 'TableServices.cc'; then $(CYGPATH_W) 'TableServices.cc'; else $(CYGPATH_W) '$(srcdir)/TableServices.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServices.Tpo $(DEPDIR)/liblivestatus_a-TableServices.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServices.cc' object='liblivestatus_a-TableServices.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServices.obj `if test -f 'TableServices.cc'; then $(CYGPATH_W) 'TableServices.cc'; else $(CYGPATH_W) '$(srcdir)/TableServices.cc'; fi` + +liblivestatus_a-TableServicesByGroup.o: TableServicesByGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServicesByGroup.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServicesByGroup.Tpo -c -o liblivestatus_a-TableServicesByGroup.o `test -f 'TableServicesByGroup.cc' || echo '$(srcdir)/'`TableServicesByGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServicesByGroup.Tpo $(DEPDIR)/liblivestatus_a-TableServicesByGroup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServicesByGroup.cc' object='liblivestatus_a-TableServicesByGroup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServicesByGroup.o `test -f 'TableServicesByGroup.cc' || echo '$(srcdir)/'`TableServicesByGroup.cc + +liblivestatus_a-TableServicesByGroup.obj: TableServicesByGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServicesByGroup.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServicesByGroup.Tpo -c -o liblivestatus_a-TableServicesByGroup.obj `if test -f 'TableServicesByGroup.cc'; then $(CYGPATH_W) 'TableServicesByGroup.cc'; else $(CYGPATH_W) '$(srcdir)/TableServicesByGroup.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServicesByGroup.Tpo $(DEPDIR)/liblivestatus_a-TableServicesByGroup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServicesByGroup.cc' object='liblivestatus_a-TableServicesByGroup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServicesByGroup.obj `if test -f 'TableServicesByGroup.cc'; then $(CYGPATH_W) 'TableServicesByGroup.cc'; else $(CYGPATH_W) '$(srcdir)/TableServicesByGroup.cc'; fi` + +liblivestatus_a-TableServicesByHostGroup.o: TableServicesByHostGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServicesByHostGroup.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServicesByHostGroup.Tpo -c -o liblivestatus_a-TableServicesByHostGroup.o `test -f 'TableServicesByHostGroup.cc' || echo '$(srcdir)/'`TableServicesByHostGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServicesByHostGroup.Tpo $(DEPDIR)/liblivestatus_a-TableServicesByHostGroup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServicesByHostGroup.cc' object='liblivestatus_a-TableServicesByHostGroup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServicesByHostGroup.o `test -f 'TableServicesByHostGroup.cc' || echo '$(srcdir)/'`TableServicesByHostGroup.cc + +liblivestatus_a-TableServicesByHostGroup.obj: TableServicesByHostGroup.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableServicesByHostGroup.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableServicesByHostGroup.Tpo -c -o liblivestatus_a-TableServicesByHostGroup.obj `if test -f 'TableServicesByHostGroup.cc'; then $(CYGPATH_W) 'TableServicesByHostGroup.cc'; else $(CYGPATH_W) '$(srcdir)/TableServicesByHostGroup.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableServicesByHostGroup.Tpo $(DEPDIR)/liblivestatus_a-TableServicesByHostGroup.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableServicesByHostGroup.cc' object='liblivestatus_a-TableServicesByHostGroup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableServicesByHostGroup.obj `if test -f 'TableServicesByHostGroup.cc'; then $(CYGPATH_W) 'TableServicesByHostGroup.cc'; else $(CYGPATH_W) '$(srcdir)/TableServicesByHostGroup.cc'; fi` + +liblivestatus_a-TableStateHistory.o: TableStateHistory.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableStateHistory.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableStateHistory.Tpo -c -o liblivestatus_a-TableStateHistory.o `test -f 'TableStateHistory.cc' || echo '$(srcdir)/'`TableStateHistory.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableStateHistory.Tpo $(DEPDIR)/liblivestatus_a-TableStateHistory.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableStateHistory.cc' object='liblivestatus_a-TableStateHistory.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableStateHistory.o `test -f 'TableStateHistory.cc' || echo '$(srcdir)/'`TableStateHistory.cc + +liblivestatus_a-TableStateHistory.obj: TableStateHistory.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableStateHistory.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableStateHistory.Tpo -c -o liblivestatus_a-TableStateHistory.obj `if test -f 'TableStateHistory.cc'; then $(CYGPATH_W) 'TableStateHistory.cc'; else $(CYGPATH_W) '$(srcdir)/TableStateHistory.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableStateHistory.Tpo $(DEPDIR)/liblivestatus_a-TableStateHistory.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableStateHistory.cc' object='liblivestatus_a-TableStateHistory.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableStateHistory.obj `if test -f 'TableStateHistory.cc'; then $(CYGPATH_W) 'TableStateHistory.cc'; else $(CYGPATH_W) '$(srcdir)/TableStateHistory.cc'; fi` + +liblivestatus_a-TableStatus.o: TableStatus.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableStatus.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableStatus.Tpo -c -o liblivestatus_a-TableStatus.o `test -f 'TableStatus.cc' || echo '$(srcdir)/'`TableStatus.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableStatus.Tpo $(DEPDIR)/liblivestatus_a-TableStatus.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableStatus.cc' object='liblivestatus_a-TableStatus.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableStatus.o `test -f 'TableStatus.cc' || echo '$(srcdir)/'`TableStatus.cc + +liblivestatus_a-TableStatus.obj: TableStatus.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableStatus.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableStatus.Tpo -c -o liblivestatus_a-TableStatus.obj `if test -f 'TableStatus.cc'; then $(CYGPATH_W) 'TableStatus.cc'; else $(CYGPATH_W) '$(srcdir)/TableStatus.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableStatus.Tpo $(DEPDIR)/liblivestatus_a-TableStatus.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableStatus.cc' object='liblivestatus_a-TableStatus.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableStatus.obj `if test -f 'TableStatus.cc'; then $(CYGPATH_W) 'TableStatus.cc'; else $(CYGPATH_W) '$(srcdir)/TableStatus.cc'; fi` + +liblivestatus_a-TableTimeperiods.o: TableTimeperiods.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableTimeperiods.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableTimeperiods.Tpo -c -o liblivestatus_a-TableTimeperiods.o `test -f 'TableTimeperiods.cc' || echo '$(srcdir)/'`TableTimeperiods.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableTimeperiods.Tpo $(DEPDIR)/liblivestatus_a-TableTimeperiods.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableTimeperiods.cc' object='liblivestatus_a-TableTimeperiods.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableTimeperiods.o `test -f 'TableTimeperiods.cc' || echo '$(srcdir)/'`TableTimeperiods.cc + +liblivestatus_a-TableTimeperiods.obj: TableTimeperiods.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TableTimeperiods.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TableTimeperiods.Tpo -c -o liblivestatus_a-TableTimeperiods.obj `if test -f 'TableTimeperiods.cc'; then $(CYGPATH_W) 'TableTimeperiods.cc'; else $(CYGPATH_W) '$(srcdir)/TableTimeperiods.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TableTimeperiods.Tpo $(DEPDIR)/liblivestatus_a-TableTimeperiods.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TableTimeperiods.cc' object='liblivestatus_a-TableTimeperiods.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TableTimeperiods.obj `if test -f 'TableTimeperiods.cc'; then $(CYGPATH_W) 'TableTimeperiods.cc'; else $(CYGPATH_W) '$(srcdir)/TableTimeperiods.cc'; fi` + +liblivestatus_a-TimeColumn.o: TimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeColumn.Tpo -c -o liblivestatus_a-TimeColumn.o `test -f 'TimeColumn.cc' || echo '$(srcdir)/'`TimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeColumn.Tpo $(DEPDIR)/liblivestatus_a-TimeColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeColumn.cc' object='liblivestatus_a-TimeColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeColumn.o `test -f 'TimeColumn.cc' || echo '$(srcdir)/'`TimeColumn.cc + +liblivestatus_a-TimeColumn.obj: TimeColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeColumn.Tpo -c -o liblivestatus_a-TimeColumn.obj `if test -f 'TimeColumn.cc'; then $(CYGPATH_W) 'TimeColumn.cc'; else $(CYGPATH_W) '$(srcdir)/TimeColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeColumn.Tpo $(DEPDIR)/liblivestatus_a-TimeColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeColumn.cc' object='liblivestatus_a-TimeColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeColumn.obj `if test -f 'TimeColumn.cc'; then $(CYGPATH_W) 'TimeColumn.cc'; else $(CYGPATH_W) '$(srcdir)/TimeColumn.cc'; fi` + +liblivestatus_a-TimeFilter.o: TimeFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeFilter.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeFilter.Tpo -c -o liblivestatus_a-TimeFilter.o `test -f 'TimeFilter.cc' || echo '$(srcdir)/'`TimeFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeFilter.Tpo $(DEPDIR)/liblivestatus_a-TimeFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeFilter.cc' object='liblivestatus_a-TimeFilter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeFilter.o `test -f 'TimeFilter.cc' || echo '$(srcdir)/'`TimeFilter.cc + +liblivestatus_a-TimeFilter.obj: TimeFilter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeFilter.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeFilter.Tpo -c -o liblivestatus_a-TimeFilter.obj `if test -f 'TimeFilter.cc'; then $(CYGPATH_W) 'TimeFilter.cc'; else $(CYGPATH_W) '$(srcdir)/TimeFilter.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeFilter.Tpo $(DEPDIR)/liblivestatus_a-TimeFilter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeFilter.cc' object='liblivestatus_a-TimeFilter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeFilter.obj `if test -f 'TimeFilter.cc'; then $(CYGPATH_W) 'TimeFilter.cc'; else $(CYGPATH_W) '$(srcdir)/TimeFilter.cc'; fi` + +liblivestatus_a-TimeperiodColumn.o: TimeperiodColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeperiodColumn.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeperiodColumn.Tpo -c -o liblivestatus_a-TimeperiodColumn.o `test -f 'TimeperiodColumn.cc' || echo '$(srcdir)/'`TimeperiodColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeperiodColumn.Tpo $(DEPDIR)/liblivestatus_a-TimeperiodColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeperiodColumn.cc' object='liblivestatus_a-TimeperiodColumn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeperiodColumn.o `test -f 'TimeperiodColumn.cc' || echo '$(srcdir)/'`TimeperiodColumn.cc + +liblivestatus_a-TimeperiodColumn.obj: TimeperiodColumn.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeperiodColumn.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeperiodColumn.Tpo -c -o liblivestatus_a-TimeperiodColumn.obj `if test -f 'TimeperiodColumn.cc'; then $(CYGPATH_W) 'TimeperiodColumn.cc'; else $(CYGPATH_W) '$(srcdir)/TimeperiodColumn.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeperiodColumn.Tpo $(DEPDIR)/liblivestatus_a-TimeperiodColumn.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeperiodColumn.cc' object='liblivestatus_a-TimeperiodColumn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeperiodColumn.obj `if test -f 'TimeperiodColumn.cc'; then $(CYGPATH_W) 'TimeperiodColumn.cc'; else $(CYGPATH_W) '$(srcdir)/TimeperiodColumn.cc'; fi` + +liblivestatus_a-TimeperiodsCache.o: TimeperiodsCache.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeperiodsCache.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeperiodsCache.Tpo -c -o liblivestatus_a-TimeperiodsCache.o `test -f 'TimeperiodsCache.cc' || echo '$(srcdir)/'`TimeperiodsCache.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeperiodsCache.Tpo $(DEPDIR)/liblivestatus_a-TimeperiodsCache.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeperiodsCache.cc' object='liblivestatus_a-TimeperiodsCache.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeperiodsCache.o `test -f 'TimeperiodsCache.cc' || echo '$(srcdir)/'`TimeperiodsCache.cc + +liblivestatus_a-TimeperiodsCache.obj: TimeperiodsCache.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-TimeperiodsCache.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-TimeperiodsCache.Tpo -c -o liblivestatus_a-TimeperiodsCache.obj `if test -f 'TimeperiodsCache.cc'; then $(CYGPATH_W) 'TimeperiodsCache.cc'; else $(CYGPATH_W) '$(srcdir)/TimeperiodsCache.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-TimeperiodsCache.Tpo $(DEPDIR)/liblivestatus_a-TimeperiodsCache.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TimeperiodsCache.cc' object='liblivestatus_a-TimeperiodsCache.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-TimeperiodsCache.obj `if test -f 'TimeperiodsCache.cc'; then $(CYGPATH_W) 'TimeperiodsCache.cc'; else $(CYGPATH_W) '$(srcdir)/TimeperiodsCache.cc'; fi` + +liblivestatus_a-Triggers.o: Triggers.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Triggers.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-Triggers.Tpo -c -o liblivestatus_a-Triggers.o `test -f 'Triggers.cc' || echo '$(srcdir)/'`Triggers.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Triggers.Tpo $(DEPDIR)/liblivestatus_a-Triggers.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Triggers.cc' object='liblivestatus_a-Triggers.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Triggers.o `test -f 'Triggers.cc' || echo '$(srcdir)/'`Triggers.cc + +liblivestatus_a-Triggers.obj: Triggers.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-Triggers.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-Triggers.Tpo -c -o liblivestatus_a-Triggers.obj `if test -f 'Triggers.cc'; then $(CYGPATH_W) 'Triggers.cc'; else $(CYGPATH_W) '$(srcdir)/Triggers.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-Triggers.Tpo $(DEPDIR)/liblivestatus_a-Triggers.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='Triggers.cc' object='liblivestatus_a-Triggers.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-Triggers.obj `if test -f 'Triggers.cc'; then $(CYGPATH_W) 'Triggers.cc'; else $(CYGPATH_W) '$(srcdir)/Triggers.cc'; fi` + +liblivestatus_a-auth.o: auth.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-auth.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-auth.Tpo -c -o liblivestatus_a-auth.o `test -f 'auth.cc' || echo '$(srcdir)/'`auth.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-auth.Tpo $(DEPDIR)/liblivestatus_a-auth.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='auth.cc' object='liblivestatus_a-auth.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-auth.o `test -f 'auth.cc' || echo '$(srcdir)/'`auth.cc + +liblivestatus_a-auth.obj: auth.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-auth.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-auth.Tpo -c -o liblivestatus_a-auth.obj `if test -f 'auth.cc'; then $(CYGPATH_W) 'auth.cc'; else $(CYGPATH_W) '$(srcdir)/auth.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-auth.Tpo $(DEPDIR)/liblivestatus_a-auth.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='auth.cc' object='liblivestatus_a-auth.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-auth.obj `if test -f 'auth.cc'; then $(CYGPATH_W) 'auth.cc'; else $(CYGPATH_W) '$(srcdir)/auth.cc'; fi` + +liblivestatus_a-global_counters.o: global_counters.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-global_counters.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-global_counters.Tpo -c -o liblivestatus_a-global_counters.o `test -f 'global_counters.cc' || echo '$(srcdir)/'`global_counters.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-global_counters.Tpo $(DEPDIR)/liblivestatus_a-global_counters.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='global_counters.cc' object='liblivestatus_a-global_counters.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-global_counters.o `test -f 'global_counters.cc' || echo '$(srcdir)/'`global_counters.cc + +liblivestatus_a-global_counters.obj: global_counters.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-global_counters.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-global_counters.Tpo -c -o liblivestatus_a-global_counters.obj `if test -f 'global_counters.cc'; then $(CYGPATH_W) 'global_counters.cc'; else $(CYGPATH_W) '$(srcdir)/global_counters.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-global_counters.Tpo $(DEPDIR)/liblivestatus_a-global_counters.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='global_counters.cc' object='liblivestatus_a-global_counters.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-global_counters.obj `if test -f 'global_counters.cc'; then $(CYGPATH_W) 'global_counters.cc'; else $(CYGPATH_W) '$(srcdir)/global_counters.cc'; fi` + +liblivestatus_a-mk_inventory.o: mk_inventory.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-mk_inventory.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-mk_inventory.Tpo -c -o liblivestatus_a-mk_inventory.o `test -f 'mk_inventory.cc' || echo '$(srcdir)/'`mk_inventory.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-mk_inventory.Tpo $(DEPDIR)/liblivestatus_a-mk_inventory.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mk_inventory.cc' object='liblivestatus_a-mk_inventory.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-mk_inventory.o `test -f 'mk_inventory.cc' || echo '$(srcdir)/'`mk_inventory.cc + +liblivestatus_a-mk_inventory.obj: mk_inventory.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-mk_inventory.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-mk_inventory.Tpo -c -o liblivestatus_a-mk_inventory.obj `if test -f 'mk_inventory.cc'; then $(CYGPATH_W) 'mk_inventory.cc'; else $(CYGPATH_W) '$(srcdir)/mk_inventory.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-mk_inventory.Tpo $(DEPDIR)/liblivestatus_a-mk_inventory.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mk_inventory.cc' object='liblivestatus_a-mk_inventory.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-mk_inventory.obj `if test -f 'mk_inventory.cc'; then $(CYGPATH_W) 'mk_inventory.cc'; else $(CYGPATH_W) '$(srcdir)/mk_inventory.cc'; fi` + +liblivestatus_a-mk_logwatch.o: mk_logwatch.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-mk_logwatch.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-mk_logwatch.Tpo -c -o liblivestatus_a-mk_logwatch.o `test -f 'mk_logwatch.cc' || echo '$(srcdir)/'`mk_logwatch.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-mk_logwatch.Tpo $(DEPDIR)/liblivestatus_a-mk_logwatch.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mk_logwatch.cc' object='liblivestatus_a-mk_logwatch.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-mk_logwatch.o `test -f 'mk_logwatch.cc' || echo '$(srcdir)/'`mk_logwatch.cc + +liblivestatus_a-mk_logwatch.obj: mk_logwatch.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-mk_logwatch.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-mk_logwatch.Tpo -c -o liblivestatus_a-mk_logwatch.obj `if test -f 'mk_logwatch.cc'; then $(CYGPATH_W) 'mk_logwatch.cc'; else $(CYGPATH_W) '$(srcdir)/mk_logwatch.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-mk_logwatch.Tpo $(DEPDIR)/liblivestatus_a-mk_logwatch.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='mk_logwatch.cc' object='liblivestatus_a-mk_logwatch.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-mk_logwatch.obj `if test -f 'mk_logwatch.cc'; then $(CYGPATH_W) 'mk_logwatch.cc'; else $(CYGPATH_W) '$(srcdir)/mk_logwatch.cc'; fi` + +liblivestatus_a-module.o: module.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-module.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-module.Tpo -c -o liblivestatus_a-module.o `test -f 'module.cc' || echo '$(srcdir)/'`module.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-module.Tpo $(DEPDIR)/liblivestatus_a-module.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='module.cc' object='liblivestatus_a-module.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-module.o `test -f 'module.cc' || echo '$(srcdir)/'`module.cc + +liblivestatus_a-module.obj: module.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-module.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-module.Tpo -c -o liblivestatus_a-module.obj `if test -f 'module.cc'; then $(CYGPATH_W) 'module.cc'; else $(CYGPATH_W) '$(srcdir)/module.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-module.Tpo $(DEPDIR)/liblivestatus_a-module.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='module.cc' object='liblivestatus_a-module.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-module.obj `if test -f 'module.cc'; then $(CYGPATH_W) 'module.cc'; else $(CYGPATH_W) '$(srcdir)/module.cc'; fi` + +liblivestatus_a-opids.o: opids.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-opids.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-opids.Tpo -c -o liblivestatus_a-opids.o `test -f 'opids.cc' || echo '$(srcdir)/'`opids.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-opids.Tpo $(DEPDIR)/liblivestatus_a-opids.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opids.cc' object='liblivestatus_a-opids.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-opids.o `test -f 'opids.cc' || echo '$(srcdir)/'`opids.cc + +liblivestatus_a-opids.obj: opids.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-opids.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-opids.Tpo -c -o liblivestatus_a-opids.obj `if test -f 'opids.cc'; then $(CYGPATH_W) 'opids.cc'; else $(CYGPATH_W) '$(srcdir)/opids.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-opids.Tpo $(DEPDIR)/liblivestatus_a-opids.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opids.cc' object='liblivestatus_a-opids.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-opids.obj `if test -f 'opids.cc'; then $(CYGPATH_W) 'opids.cc'; else $(CYGPATH_W) '$(srcdir)/opids.cc'; fi` + +liblivestatus_a-pnp4nagios.o: pnp4nagios.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-pnp4nagios.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-pnp4nagios.Tpo -c -o liblivestatus_a-pnp4nagios.o `test -f 'pnp4nagios.cc' || echo '$(srcdir)/'`pnp4nagios.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-pnp4nagios.Tpo $(DEPDIR)/liblivestatus_a-pnp4nagios.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pnp4nagios.cc' object='liblivestatus_a-pnp4nagios.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-pnp4nagios.o `test -f 'pnp4nagios.cc' || echo '$(srcdir)/'`pnp4nagios.cc + +liblivestatus_a-pnp4nagios.obj: pnp4nagios.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-pnp4nagios.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-pnp4nagios.Tpo -c -o liblivestatus_a-pnp4nagios.obj `if test -f 'pnp4nagios.cc'; then $(CYGPATH_W) 'pnp4nagios.cc'; else $(CYGPATH_W) '$(srcdir)/pnp4nagios.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-pnp4nagios.Tpo $(DEPDIR)/liblivestatus_a-pnp4nagios.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='pnp4nagios.cc' object='liblivestatus_a-pnp4nagios.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-pnp4nagios.obj `if test -f 'pnp4nagios.cc'; then $(CYGPATH_W) 'pnp4nagios.cc'; else $(CYGPATH_W) '$(srcdir)/pnp4nagios.cc'; fi` + +liblivestatus_a-strutil.o: strutil.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-strutil.o -MD -MP -MF $(DEPDIR)/liblivestatus_a-strutil.Tpo -c -o liblivestatus_a-strutil.o `test -f 'strutil.cc' || echo '$(srcdir)/'`strutil.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-strutil.Tpo $(DEPDIR)/liblivestatus_a-strutil.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='strutil.cc' object='liblivestatus_a-strutil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-strutil.o `test -f 'strutil.cc' || echo '$(srcdir)/'`strutil.cc + +liblivestatus_a-strutil.obj: strutil.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -MT liblivestatus_a-strutil.obj -MD -MP -MF $(DEPDIR)/liblivestatus_a-strutil.Tpo -c -o liblivestatus_a-strutil.obj `if test -f 'strutil.cc'; then $(CYGPATH_W) 'strutil.cc'; else $(CYGPATH_W) '$(srcdir)/strutil.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/liblivestatus_a-strutil.Tpo $(DEPDIR)/liblivestatus_a-strutil.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='strutil.cc' object='liblivestatus_a-strutil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblivestatus_a_CPPFLAGS) $(CPPFLAGS) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c -o liblivestatus_a-strutil.obj `if test -f 'strutil.cc'; then $(CYGPATH_W) 'strutil.cc'; else $(CYGPATH_W) '$(srcdir)/strutil.cc'; fi` + +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: $(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 $(LIBRARIES) $(PROGRAMS) all-local +installdirs: + for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)"; 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-binPROGRAMS clean-generic clean-local \ + clean-pkglibLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -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-data-local + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-pkglibLIBRARIES + +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 -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-pkglibLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \ + clean-binPROGRAMS clean-generic clean-local \ + clean-pkglibLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-data-local 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-pkglibLIBRARIES install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-pkglibLIBRARIES + +.PRECIOUS: Makefile + + +CLANG_VERSION ?= 8 + +BEAR ?= bear +CPPCHECK ?= cppcheck +DOXYGEN ?= doxygen +IWYU_TOOL ?= iwyu_tool +RUN_CLANG_TIDY ?= \ + $(abs_top_srcdir)/scripts/run-clang-tidy.py \ + -clang-tidy-binary=clang-tidy-$(CLANG_VERSION) \ + -clang-apply-replacements-binary=clang-apply-replacements-$(CLANG_VERSION) + +.PHONY: tidy iwyu cppcheck cppcheck-xml documentation + +livestatus.o: $(liblivestatus_a_OBJECTS) +# Note: libstdc++fs is only available as a static library, so we are lucky. For +# RE2 we make sure that this is the case, too. + $(CXXLINK) -shared $^ -lstdc++fs -lpthread -static-libstdc++ @BOOST_LDFLAGS@ @BOOST_ASIO_LIB@ @RE2_LDFLAGS@ @RE2_LIBS@ +# To make sure we can dlopen() our NEB later + $(CXX) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) -c NagiosMockup.cc -o NagiosMockup.o + $(CXX) $(liblivestatus_a_CXXFLAGS) $(CXXFLAGS) NagiosMockup.o $@ -o NagiosMockup + $(RM) NagiosMockup + +compile_commands.json: Makefile $(wildcard *.cc *.h) + $(MAKE) clean + $(BEAR) $(MAKE) -j4 + +tidy: compile_commands.json + $(RUN_CLANG_TIDY) -quiet -j6 + +iwyu: compile_commands.json + $(IWYU_TOOL) --output-format=clang -p . -- --mapping_file=$(abs_top_srcdir)/livestatus/iwyu-mappings/check_mk.imp + +cppcheck: compile_commands.json + $(CPPCHECK) -UCMC --enable=all --suppressions-list=$(abs_top_srcdir)/.cppcheck-suppressions --inline-suppr --project=compile_commands.json --quiet --template=gcc + +cppcheck-xml: compile_commands.json + $(CPPCHECK) -UCMC --enable=all --suppressions-list=$(abs_top_srcdir)/.cppcheck-suppressions --inline-suppr --project=compile_commands.json --quiet --template=gcc --xml --xml-version=2 2> cppcheck-result.xml + +documentation: + $(DOXYGEN) doc/Doxyfile + +all-local: livestatus.o + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(pkglibdir) + $(INSTALL_PROGRAM) livestatus.o $(DESTDIR)$(pkglibdir) + rm -f $(DESTDIR)$(pkglibdir)/liblivestatus.a + +clean-local: + rm -rf *~ compile_commands.json cppcheck-result.xml html + +# 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/src/MetricsColumn.cc b/src/MetricsColumn.cc new file mode 100644 index 0000000..c347b54 --- /dev/null +++ b/src/MetricsColumn.cc @@ -0,0 +1,59 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "MetricsColumn.h" +#include "Row.h" + +#ifdef CMC +#include +#include +#include "Core.h" +#include "Metric.h" +#include "MonitoringCore.h" +#include "Object.h" +#include "RRDBackend.h" +#include "RRDInfoCache.h" +#include "State.h" +#include "cmc.h" +#endif + +std::vector MetricsColumn::getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + std::vector metrics; +#ifdef CMC + if (auto object = columnData(row)) { + if (object->isEnabled(State::Enable::performance_data)) { + auto names = _mc->impl()->_rrd_backend.infoFor(object)._names; + std::transform( + names.begin(), names.end(), std::back_inserter(metrics), + [](const Metric::MangledName &name) { return name.string(); }); + } + } +#else + (void)_mc; + (void)row; +#endif + return metrics; +} diff --git a/src/MetricsColumn.h b/src/MetricsColumn.h new file mode 100644 index 0000000..f0d05a0 --- /dev/null +++ b/src/MetricsColumn.h @@ -0,0 +1,54 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef MetricsColumn_h +#define MetricsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class MonitoringCore; +class Row; + +class MetricsColumn : public ListColumn { +public: + MetricsColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset, MonitoringCore *mc) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) {} + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *const _mc; +}; + +#endif // MetricsColumn_h diff --git a/src/MonitoringCore.h b/src/MonitoringCore.h new file mode 100644 index 0000000..5a0e053 --- /dev/null +++ b/src/MonitoringCore.h @@ -0,0 +1,122 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef MonitoringCore_h +#define MonitoringCore_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Triggers.h" +#include "auth.h" +#include "data_encoding.h" +class Logger; + +struct Command { + std::string _name; + std::string _command_line; +}; + +struct DowntimeData { + unsigned long _id; + std::string _author; + std::string _comment; +}; + +struct CommentData { + unsigned long _id; + std::string _author; + std::string _comment; + uint32_t _entry_type; // TODO(sp) Move Comment::Type here + std::chrono::system_clock::time_point _entry_time; +}; + +/// An abstraction layer for the monitoring core (nagios or cmc) +class MonitoringCore { +public: + class Contact; + class ContactGroup; + class Host; + class Service; + class TimePeriod; + + virtual ~MonitoringCore() = default; + + virtual Host *getHostByDesignation(const std::string &designation) = 0; + virtual ContactGroup *find_contactgroup(const std::string &name) = 0; + + virtual bool host_has_contact(const Host *host, const Contact *contact) = 0; + virtual bool is_contact_member_of_contactgroup(const ContactGroup *group, + const Contact *contact) = 0; + + virtual std::chrono::system_clock::time_point last_logfile_rotation() = 0; + [[nodiscard]] virtual size_t maxLinesPerLogFile() const = 0; + + [[nodiscard]] virtual Command find_command(std::string name) const = 0; + [[nodiscard]] virtual std::vector commands() const = 0; + + virtual std::vector downtimes_for_host( + const Host *) const = 0; + virtual std::vector downtimes_for_service( + const Service *) const = 0; + virtual std::vector comments_for_host(const Host *) const = 0; + virtual std::vector comments_for_service( + const Service *) const = 0; + + virtual bool mkeventdEnabled() = 0; + + virtual std::string mkeventdSocketPath() = 0; + virtual std::string mkLogwatchPath() = 0; + virtual std::string mkInventoryPath() = 0; + virtual std::string structuredStatusPath() = 0; + virtual std::string pnpPath() = 0; + virtual std::string historyFilePath() = 0; + virtual std::string logArchivePath() = 0; + virtual Encoding dataEncoding() = 0; + virtual size_t maxResponseSize() = 0; + virtual size_t maxCachedMessages() = 0; + + [[nodiscard]] virtual AuthorizationKind hostAuthorization() const = 0; + [[nodiscard]] virtual AuthorizationKind serviceAuthorization() const = 0; + [[nodiscard]] virtual AuthorizationKind groupAuthorization() const = 0; + + virtual Logger *loggerLivestatus() = 0; + + virtual Triggers &triggers() = 0; + + virtual size_t numQueuedNotifications() = 0; + virtual size_t numQueuedAlerts() = 0; + + // Our escape hatch, this should die in the long run... + template + [[nodiscard]] T *impl() const { + return static_cast(implInternal()); + } + +private: + [[nodiscard]] virtual void *implInternal() const = 0; +}; + +#endif // MonitoringCore_h diff --git a/src/NagiosMockup.cc b/src/NagiosMockup.cc new file mode 100644 index 0000000..0304233 --- /dev/null +++ b/src/NagiosMockup.cc @@ -0,0 +1,114 @@ +#include + +extern "C" { +// dummy types ----------------------------------------------------------------- + +struct circular_buffer { + int dummy; +}; +struct command; +struct contactgroup; +struct contact; +struct hostgroup; +struct host; +struct scheduled_downtime; +struct servicegroup; +struct service; +struct timeperiod; + +// official exports ------------------------------------------------------------ + +int accept_passive_host_checks; +int accept_passive_service_checks; +int check_time_against_period(time_t /*unused*/, timeperiod * /*unused*/) { + return 0; +} +command *find_command(char * /*unused*/) { return nullptr; } +contact *find_contact(char * /*unused*/) { return nullptr; } +contactgroup *find_contactgroup(char * /*unused*/) { return nullptr; } +host *find_host(char * /*unused*/) { return nullptr; } +hostgroup *find_hostgroup(char * /*unused*/) { return nullptr; } +service *find_service(char * /*unused*/, char * /*unused*/) { return nullptr; } +servicegroup *find_servicegroup(char * /*unused*/) { return nullptr; } +time_t get_next_log_rotation_time(void) { return 0; } +char *get_program_version(void) { return nullptr; } +int is_contact_for_host(host * /*unused*/, contact * /*unused*/) { return 0; } +int is_contact_for_service(service * /*unused*/, contact * /*unused*/) { + return 0; +} +int is_contact_member_of_contactgroup(contactgroup * /*unused*/, + contact * /*unused*/) { + return 0; +} +int is_escalated_contact_for_host(host * /*unused*/, contact * /*unused*/) { + return 0; +} +int is_escalated_contact_for_service(service * /*unused*/, + contact * /*unused*/) { + return 0; +} +time_t last_command_check; +time_t last_log_rotation; +int neb_deregister_callback(int /*unused*/, int (*/*unused*/)(int, void *)) { + return 0; +} +int neb_register_callback(int /*unused*/, void * /*unused*/, int /*unused*/, + int (*/*unused*/)(int, void *)) { + return 0; +} +int obsess_over_hosts; +int obsess_over_services; +int process_performance_data; +int process_external_command1(char * /*unused*/) { return 0; } +time_t program_start; +int rotate_log_file(time_t /*unused*/) { return 0; } +int schedule_new_event(int /*unused*/, int /*unused*/, time_t /*unused*/, + int /*unused*/, unsigned long /*unused*/, + void * /*unused*/, int /*unused*/, void * /*unused*/, + void * /*unused*/, int /*unused*/) { + return 0; +} +int submit_external_command(char * /*unused*/, int * /*unused*/) { return 0; } +int write_to_all_logs(char * /*unused*/, unsigned long /*unused*/) { return 0; } + +// inofficial exports ---------------------------------------------------------- + +int check_external_commands; +int check_host_freshness; +int check_service_freshness; +command *command_list; +contactgroup *contactgroup_list; +contact *contact_list; +int enable_environment_macros; +int enable_event_handlers; +int enable_flap_detection; +int enable_notifications; +unsigned long event_broker_options; +int execute_host_checks; +int execute_service_checks; +circular_buffer external_command_buffer; +int external_command_buffer_slots; +hostgroup *hostgroup_list; +host *host_list; +int interval_length; +char *log_archive_path; +char log_file[256]; +int log_initial_states; +char *macro_user[256]; +int nagios_pid; +scheduled_downtime *scheduled_downtime_list; +servicegroup *servicegroup_list; +service *service_list; +timeperiod *timeperiod_list; + +// imports --------------------------------------------------------------------- + +int nebmodule_init(int flags, char *args, void *handle); +int nebmodule_deinit(int flags, int reason); +} + +int main() { + nebmodule_init(0, nullptr, nullptr); + nebmodule_deinit(0, 0); + return 0; +} diff --git a/src/NullColumn.cc b/src/NullColumn.cc new file mode 100644 index 0000000..5ddbc92 --- /dev/null +++ b/src/NullColumn.cc @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "NullColumn.h" +#include +#include "Renderer.h" +#include "Row.h" + +void NullColumn::output(Row /* row */, RowRenderer& r, + const contact* /* auth_user */, + std::chrono::seconds /*timezone_offset*/) const { + r.output(Null()); +} + +std::unique_ptr NullColumn::createFilter( + Filter::Kind /*unused*/, RelationalOperator /*unused*/, + const std::string& /*unused*/) const { + throw std::runtime_error("filtering on null column not supported"); +} + +std::unique_ptr NullColumn::createAggregator( + AggregationFactory /*factory*/) const { + throw std::runtime_error("aggregating on null column not supported"); +} diff --git a/src/NullColumn.h b/src/NullColumn.h new file mode 100644 index 0000000..4094b35 --- /dev/null +++ b/src/NullColumn.h @@ -0,0 +1,61 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef NullColumn_h +#define NullColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class NullColumn : public Column { +public: + NullColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset) + : Column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] ColumnType type() const override { return ColumnType::null; } + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; +}; + +#endif // NullColumn_h diff --git a/src/OStreamStateSaver.h b/src/OStreamStateSaver.h new file mode 100644 index 0000000..bb3c889 --- /dev/null +++ b/src/OStreamStateSaver.h @@ -0,0 +1,51 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OStreamStateSaver_h +#define OStreamStateSaver_h + +#include "config.h" // IWYU pragma: keep +#include + +class OStreamStateSaver { +public: + explicit OStreamStateSaver(std::ostream &os) + : _os(os) + , _old_flags(_os.flags()) + , _old_precision(_os.precision()) + , _old_fill(_os.fill()) {} + ~OStreamStateSaver() { + _os.fill(_old_fill); + _os.precision(_old_precision); + _os.flags(_old_flags); + } + +private: + std::ostream &_os; + std::ios_base::fmtflags _old_flags; + std::streamsize _old_precision; + char _old_fill; +}; + +#endif // OStreamStateSaver_h diff --git a/src/OffsetBoolColumn.cc b/src/OffsetBoolColumn.cc new file mode 100644 index 0000000..623a5fc --- /dev/null +++ b/src/OffsetBoolColumn.cc @@ -0,0 +1,34 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetBoolColumn.h" +#include "Row.h" + +int32_t OffsetBoolColumn::getValue(Row row, + const contact* /* auth_user */) const { + if (auto p = columnData(row)) { + return *p ? 1 : 0; + } + return 0; +} diff --git a/src/OffsetBoolColumn.h b/src/OffsetBoolColumn.h new file mode 100644 index 0000000..44e73c6 --- /dev/null +++ b/src/OffsetBoolColumn.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetBoolColumn_h +#define OffsetBoolColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +#include "contact_fwd.h" +class Row; + +class OffsetBoolColumn : public IntColumn { +public: + OffsetBoolColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + int32_t getValue(Row row, const contact* auth_user) const override; +}; + +#endif // OffsetBoolColumn_h diff --git a/src/OffsetDoubleColumn.cc b/src/OffsetDoubleColumn.cc new file mode 100644 index 0000000..b625d2a --- /dev/null +++ b/src/OffsetDoubleColumn.cc @@ -0,0 +1,33 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetDoubleColumn.h" +#include "Row.h" + +double OffsetDoubleColumn::getValue(Row row) const { + if (auto p = columnData(row)) { + return *p; + } + return 0; +} diff --git a/src/OffsetDoubleColumn.h b/src/OffsetDoubleColumn.h new file mode 100644 index 0000000..bd304bd --- /dev/null +++ b/src/OffsetDoubleColumn.h @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetDoubleColumn_h +#define OffsetDoubleColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "DoubleColumn.h" +class Row; + +class OffsetDoubleColumn : public DoubleColumn { +public: + OffsetDoubleColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : DoubleColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + [[nodiscard]] double getValue(Row row) const override; +}; + +#endif // OffsetDoubleColumn_h diff --git a/src/OffsetIntColumn.cc b/src/OffsetIntColumn.cc new file mode 100644 index 0000000..b8c59d1 --- /dev/null +++ b/src/OffsetIntColumn.cc @@ -0,0 +1,34 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetIntColumn.h" +#include "Row.h" + +int32_t OffsetIntColumn::getValue(Row row, + const contact* /* auth_user */) const { + if (auto p = columnData(row)) { + return static_cast(*p); + } + return 0; +} diff --git a/src/OffsetIntColumn.h b/src/OffsetIntColumn.h new file mode 100644 index 0000000..ee27f80 --- /dev/null +++ b/src/OffsetIntColumn.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetIntColumn_h +#define OffsetIntColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +#include "contact_fwd.h" +class Row; + +class OffsetIntColumn : public IntColumn { +public: + OffsetIntColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + int32_t getValue(Row row, const contact* auth_user) const override; +}; + +#endif // OffsetIntColumn_h diff --git a/src/OffsetPerfdataColumn.cc b/src/OffsetPerfdataColumn.cc new file mode 100644 index 0000000..2d723db --- /dev/null +++ b/src/OffsetPerfdataColumn.cc @@ -0,0 +1,32 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetPerfdataColumn.h" +#include "Aggregator.h" +#include "PerfdataAggregator.h" + +std::unique_ptr OffsetPerfdataColumn::createAggregator( + AggregationFactory factory) const { + return std::make_unique(factory, this); +} diff --git a/src/OffsetPerfdataColumn.h b/src/OffsetPerfdataColumn.h new file mode 100644 index 0000000..33723d1 --- /dev/null +++ b/src/OffsetPerfdataColumn.h @@ -0,0 +1,47 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetPerfdataColumn_h +#define OffsetPerfdataColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "Column.h" +#include "OffsetStringColumn.h" +class Aggregator; + +class OffsetPerfdataColumn : public OffsetStringColumn { +public: + OffsetPerfdataColumn(const std::string& name, + const std::string& description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset) + : OffsetStringColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; +}; + +#endif // OffsetPerfdataColumn_h diff --git a/src/OffsetSStringColumn.cc b/src/OffsetSStringColumn.cc new file mode 100644 index 0000000..d5c8614 --- /dev/null +++ b/src/OffsetSStringColumn.cc @@ -0,0 +1,33 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetSStringColumn.h" +#include "Row.h" + +std::string OffsetSStringColumn::getValue(Row row) const { + if (auto p = columnData(row)) { + return p == nullptr ? "" : *p; + } + return ""; +} diff --git a/src/OffsetSStringColumn.h b/src/OffsetSStringColumn.h new file mode 100644 index 0000000..34579ec --- /dev/null +++ b/src/OffsetSStringColumn.h @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetSStringColumn_h +#define OffsetSStringColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "StringColumn.h" +class Row; + +class OffsetSStringColumn : public StringColumn { +public: + OffsetSStringColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : StringColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + [[nodiscard]] std::string getValue(Row row) const override; +}; + +#endif // OffsetSStringColumn_h diff --git a/src/OffsetStringColumn.cc b/src/OffsetStringColumn.cc new file mode 100644 index 0000000..ae4054b --- /dev/null +++ b/src/OffsetStringColumn.cc @@ -0,0 +1,33 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetStringColumn.h" +#include "Row.h" + +std::string OffsetStringColumn::getValue(Row row) const { + if (auto p = columnData(row)) { + return *p == nullptr ? "" : *p; + } + return ""; +} diff --git a/src/OffsetStringColumn.h b/src/OffsetStringColumn.h new file mode 100644 index 0000000..007990c --- /dev/null +++ b/src/OffsetStringColumn.h @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetStringColumn_h +#define OffsetStringColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "StringColumn.h" +class Row; + +class OffsetStringColumn : public StringColumn { +public: + OffsetStringColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : StringColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + [[nodiscard]] std::string getValue(Row row) const override; +}; + +#endif // OffsetStringColumn_h diff --git a/src/OffsetStringHostMacroColumn.cc b/src/OffsetStringHostMacroColumn.cc new file mode 100644 index 0000000..34efd80 --- /dev/null +++ b/src/OffsetStringHostMacroColumn.cc @@ -0,0 +1,34 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetStringHostMacroColumn.h" +#include "Row.h" + +const host *OffsetStringHostMacroColumn::getHost(Row row) const { + return columnData(row); +} + +const service *OffsetStringHostMacroColumn::getService(Row /*unused*/) const { + return nullptr; +} diff --git a/src/OffsetStringHostMacroColumn.h b/src/OffsetStringHostMacroColumn.h new file mode 100644 index 0000000..99b40ef --- /dev/null +++ b/src/OffsetStringHostMacroColumn.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetStringHostMacroColumn_h +#define OffsetStringHostMacroColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "OffsetStringMacroColumn.h" +#include "nagios.h" +class Row; + +class OffsetStringHostMacroColumn : public OffsetStringMacroColumn { +public: + OffsetStringHostMacroColumn(const std::string &name, + const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : OffsetStringMacroColumn(name, description, indirect_offset, + extra_offset, extra_extra_offset, offset) {} + +private: + [[nodiscard]] const host *getHost(Row row) const override; + [[nodiscard]] const service *getService(Row row) const override; +}; + +#endif // OffsetStringHostMacroColumn_h diff --git a/src/OffsetStringMacroColumn.cc b/src/OffsetStringMacroColumn.cc new file mode 100644 index 0000000..cbe4d7e --- /dev/null +++ b/src/OffsetStringMacroColumn.cc @@ -0,0 +1,162 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetStringMacroColumn.h" +#include +#include +#include "Column.h" +#include "RegExp.h" +#include "Row.h" + +std::string OffsetStringMacroColumn::getValue(Row row) const { + if (auto p = columnData(row)) { + auto s = offset_cast(p, _string_offset); + return *s == nullptr ? "" + : expandMacros(*s, getHost(row), getService(row)); + } + return ""; +} + +// static +std::string OffsetStringMacroColumn::expandMacros(const std::string &raw, + const host *hst, + const service *svc) { + // search for macro names, beginning with $ + std::string result; + const char *scan = raw.c_str(); + while (*scan != 0) { + const char *dollar = strchr(scan, '$'); + if (dollar == nullptr) { + result += scan; + break; + } + result += std::string(scan, dollar - scan); + const char *otherdollar = strchr(dollar + 1, '$'); + if (otherdollar == nullptr) { // unterminated macro, do not expand + result += dollar; + break; + } + std::string macroname = + std::string(dollar + 1, otherdollar - dollar - 1); + const char *replacement = expandMacro(macroname.c_str(), hst, svc); + if (replacement != nullptr) { + result += replacement; + } else { + result += std::string( + dollar, otherdollar - dollar + 1); // leave macro unexpanded + } + scan = otherdollar + 1; + } + return result; +} + +// static +const char *OffsetStringMacroColumn::expandMacro(const char *macroname, + const host *hst, + const service *svc) { + // host macros + if (strcmp(macroname, "HOSTNAME") == 0) { + return hst->name; + } + if (strcmp(macroname, "HOSTDISPLAYNAME") == 0) { + return hst->display_name; + } + if (strcmp(macroname, "HOSTALIAS") == 0) { + return hst->alias; + } + if (strcmp(macroname, "HOSTADDRESS") == 0) { + return hst->address; + } + if (strcmp(macroname, "HOSTOUTPUT") == 0) { + return hst->plugin_output; + } + if (strcmp(macroname, "LONGHOSTOUTPUT") == 0) { + return hst->long_plugin_output; + } + if (strcmp(macroname, "HOSTPERFDATA") == 0) { + return hst->perf_data; + } + if (strcmp(macroname, "HOSTCHECKCOMMAND") == 0) { +#ifndef NAGIOS4 + return hst->host_check_command; +#else + return hst->check_command; +#endif // NAGIOS4 + } + if (strncmp(macroname, "_HOST", 5) == 0) { // custom macro + return expandCustomVariables(macroname + 5, hst->custom_variables); + + // service macros + } + if (svc != nullptr) { + if (strcmp(macroname, "SERVICEDESC") == 0) { + return svc->description; + } + if (strcmp(macroname, "SERVICEDISPLAYNAME") == 0) { + return svc->display_name; + } + if (strcmp(macroname, "SERVICEOUTPUT") == 0) { + return svc->plugin_output; + } + if (strcmp(macroname, "LONGSERVICEOUTPUT") == 0) { + return svc->long_plugin_output; + } + if (strcmp(macroname, "SERVICEPERFDATA") == 0) { + return svc->perf_data; + } + if (strcmp(macroname, "SERVICECHECKCOMMAND") == 0) { +#ifndef NAGIOS4 + return svc->service_check_command; +#else + return svc->check_command; +#endif // NAGIOS4 + } + if (strncmp(macroname, "_SERVICE", 8) == 0) { // custom macro + return expandCustomVariables(macroname + 8, svc->custom_variables); + } + } + + // USER macros + if (strncmp(macroname, "USER", 4) == 0) { + int n = atoi(macroname + 4); + if (n > 0 && n <= MAX_USER_MACROS) { + extern char *macro_user[MAX_USER_MACROS]; + return macro_user[n - 1]; + } + } + + return nullptr; +} + +// static +const char *OffsetStringMacroColumn::expandCustomVariables( + const char *varname, const customvariablesmember *custvars) { + RegExp regExp(varname, RegExp::Case::ignore, RegExp::Syntax::literal); + for (; custvars != nullptr; custvars = custvars->next) { + if (regExp.match(custvars->variable_name)) { + return custvars->variable_value; + } + } + return nullptr; +} diff --git a/src/OffsetStringMacroColumn.h b/src/OffsetStringMacroColumn.h new file mode 100644 index 0000000..4f2a885 --- /dev/null +++ b/src/OffsetStringMacroColumn.h @@ -0,0 +1,60 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetStringMacroColumn_h +#define OffsetStringMacroColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "StringColumn.h" +#include "nagios.h" +class Row; + +class OffsetStringMacroColumn : public StringColumn { +public: + OffsetStringMacroColumn(const std::string &name, + const std::string &description, int indirect_offset, + int extra_offset, int extra_extra_offset, + int offset) + : StringColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, 0) + , _string_offset(offset) {} + + [[nodiscard]] std::string getValue(Row row) const override; + + [[nodiscard]] virtual const host *getHost(Row) const = 0; + [[nodiscard]] virtual const service *getService(Row) const = 0; + +private: + const int _string_offset; + + static std::string expandMacros(const std::string &raw, const host *hst, + const service *svc); + static const char *expandMacro(const char *macroname, const host *hst, + const service *svc); + static const char *expandCustomVariables( + const char *varname, const customvariablesmember *custvars); +}; + +#endif // OffsetStringMacroColumn_h diff --git a/src/OffsetStringServiceMacroColumn.cc b/src/OffsetStringServiceMacroColumn.cc new file mode 100644 index 0000000..865774d --- /dev/null +++ b/src/OffsetStringServiceMacroColumn.cc @@ -0,0 +1,37 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetStringServiceMacroColumn.h" +#include "Row.h" + +const host *OffsetStringServiceMacroColumn::getHost(Row row) const { + if (auto svc = getService(row)) { + return svc->host_ptr; + } + return nullptr; +} + +const service *OffsetStringServiceMacroColumn::getService(Row row) const { + return columnData(row); +} diff --git a/src/OffsetStringServiceMacroColumn.h b/src/OffsetStringServiceMacroColumn.h new file mode 100644 index 0000000..fd0ed24 --- /dev/null +++ b/src/OffsetStringServiceMacroColumn.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetStringServiceMacroColumn_h +#define OffsetStringServiceMacroColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "OffsetStringMacroColumn.h" +#include "nagios.h" +class Row; + +class OffsetStringServiceMacroColumn : public OffsetStringMacroColumn { +public: + OffsetStringServiceMacroColumn(const std::string &name, + const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : OffsetStringMacroColumn(name, description, indirect_offset, + extra_offset, extra_extra_offset, offset) {} + +private: + [[nodiscard]] const host *getHost(Row row) const override; + [[nodiscard]] const service *getService(Row row) const override; +}; + +#endif // OffsetStringServiceMacroColumn_h diff --git a/src/OffsetTimeColumn.cc b/src/OffsetTimeColumn.cc new file mode 100644 index 0000000..22c39e6 --- /dev/null +++ b/src/OffsetTimeColumn.cc @@ -0,0 +1,35 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OffsetTimeColumn.h" +#include +#include "Row.h" + +std::chrono::system_clock::time_point OffsetTimeColumn::getRawValue( + Row row) const { + if (auto p = columnData(row)) { + return std::chrono::system_clock::from_time_t(*p); + } + return {}; +} diff --git a/src/OffsetTimeColumn.h b/src/OffsetTimeColumn.h new file mode 100644 index 0000000..80c93f4 --- /dev/null +++ b/src/OffsetTimeColumn.h @@ -0,0 +1,47 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OffsetTimeColumn_h +#define OffsetTimeColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "TimeColumn.h" +class Row; + +class OffsetTimeColumn : public TimeColumn { +public: + OffsetTimeColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : TimeColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + +private: + [[nodiscard]] std::chrono::system_clock::time_point getRawValue( + Row row) const override; +}; + +#endif // OffsetTimeColumn_h diff --git a/src/OringFilter.cc b/src/OringFilter.cc new file mode 100644 index 0000000..5d5eb00 --- /dev/null +++ b/src/OringFilter.cc @@ -0,0 +1,174 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OringFilter.h" +#include +#include +#include +#include +#include +#include +#include "AndingFilter.h" +#include "Filter.h" +#include "Row.h" + +// static +std::unique_ptr OringFilter::make(Kind kind, Filters subfilters) { + Filters filters; + for (const auto &filter : subfilters) { + if (filter->is_tautology()) { + return AndingFilter::make(kind, Filters()); + } + auto disjuncts = filter->disjuncts(); + filters.insert(filters.end(), + std::make_move_iterator(disjuncts.begin()), + std::make_move_iterator(disjuncts.end())); + } + return filters.size() == 1 ? std::move(filters[0]) + : std::make_unique( + kind, std::move(filters), Secret()); +} + +bool OringFilter::accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const { + for (const auto &filter : _subfilters) { + if (filter->accepts(row, auth_user, timezone_offset)) { + return true; + } + } + return false; +} + +std::unique_ptr OringFilter::partialFilter( + std::function predicate) const { + Filters filters; + std::transform( + _subfilters.begin(), _subfilters.end(), std::back_inserter(filters), + [&](const auto &filter) { return filter->partialFilter(predicate); }); + return make(kind(), std::move(filters)); +} + +std::optional OringFilter::stringValueRestrictionFor( + const std::string &column_name) const { + std::optional restriction; + for (const auto &filter : _subfilters) { + if (auto current = filter->stringValueRestrictionFor(column_name)) { + if (!restriction) { + restriction = current; // First restriction? Take it. + } else if (restriction != current) { + return {}; // Different restrictions? Give up. + } + } else { + return {}; // No restriction for subfilter? Give up. + } + } + return restriction; +} + +std::optional OringFilter::greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + std::optional result; + for (const auto &filter : _subfilters) { + if (auto glb = + filter->greatestLowerBoundFor(column_name, timezone_offset)) { + result = result ? std::min(*result, *glb) : glb; + } + } + return result; +} + +std::optional OringFilter::leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + std::optional result; + for (const auto &filter : _subfilters) { + if (auto lub = + filter->leastUpperBoundFor(column_name, timezone_offset)) { + result = result ? std::max(*result, *lub) : lub; + } + } + return result; +} + +std::optional> OringFilter::valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + std::optional> result; + for (const auto &filter : _subfilters) { + if (auto foo = filter->valueSetLeastUpperBoundFor(column_name, + timezone_offset)) { + result = result ? (*result | *foo) : foo; + } + } + return result; +} + +std::unique_ptr OringFilter::copy() const { + return make(kind(), disjuncts()); +} + +std::unique_ptr OringFilter::negate() const { + Filters filters; + std::transform(_subfilters.begin(), _subfilters.end(), + std::back_inserter(filters), + [](const auto &filter) { return filter->negate(); }); + return AndingFilter::make(kind(), std::move(filters)); +} + +bool OringFilter::is_tautology() const { return false; } + +bool OringFilter::is_contradiction() const { return _subfilters.empty(); } + +Filters OringFilter::disjuncts() const { + Filters filters; + std::transform(_subfilters.begin(), _subfilters.end(), + std::back_inserter(filters), + [](const auto &filter) { return filter->copy(); }); + return filters; +} + +Filters OringFilter::conjuncts() const { + Filters filters; + filters.push_back(copy()); + return filters; +} + +std::ostream &OringFilter::print(std::ostream &os) const { + for (const auto &filter : _subfilters) { + os << *filter << "\\n"; + } + switch (kind()) { + case Kind::row: + os << "Or"; + break; + case Kind::stats: + os << "StatsOr"; + break; + case Kind::wait_condition: + os << "WaitConditionOr"; + break; + } + return os << ": " << _subfilters.size(); +} diff --git a/src/OringFilter.h b/src/OringFilter.h new file mode 100644 index 0000000..4b52fc7 --- /dev/null +++ b/src/OringFilter.h @@ -0,0 +1,81 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OringFilter_h +#define OringFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Filter.h" +#include "contact_fwd.h" +class Column; +class Row; + +class OringFilter : public Filter { + struct Secret {}; + +public: + static std::unique_ptr make(Kind kind, Filters subfilters); + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + std::unique_ptr partialFilter( + std::function predicate) const override; + [[nodiscard]] std::optional stringValueRestrictionFor( + const std::string &column_name) const override; + [[nodiscard]] std::optional greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::optional leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::optional> valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + [[nodiscard]] bool is_tautology() const override; + [[nodiscard]] bool is_contradiction() const override; + [[nodiscard]] Filters disjuncts() const override; + [[nodiscard]] Filters conjuncts() const override; + + // NOTE: This is effectively private, but it can't be declared like this + // because of std::make_unique. + OringFilter(Kind kind, Filters subfilters, Secret /*unused*/) + : Filter(kind), _subfilters(std::move(subfilters)) {} + +private: + Filters _subfilters; + + std::ostream &print(std::ostream &os) const override; +}; + +#endif // OringFilter_h diff --git a/src/OutputBuffer.cc b/src/OutputBuffer.cc new file mode 100644 index 0000000..84b7ea2 --- /dev/null +++ b/src/OutputBuffer.cc @@ -0,0 +1,96 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "OutputBuffer.h" +#include +#include +#include +#include +#include "Logger.h" +#include "Poller.h" + +OutputBuffer::OutputBuffer(int fd, const bool &termination_flag, Logger *logger) + : _fd(fd) + , _termination_flag(termination_flag) + , _logger(logger) + // TODO(sp) This is really the wrong default because it hides some early + // errors, e.g. an unknown command. But we can't change this easily because + // of legacy reasons... :-/ + , _response_header(ResponseHeader::off) + , _response_code(ResponseCode::ok) {} + +OutputBuffer::~OutputBuffer() { flush(); } + +void OutputBuffer::flush() { + if (_response_header == ResponseHeader::fixed16) { + if (_response_code != ResponseCode::ok) { + _os.clear(); + _os.str(""); + _os << _error_message; + } + auto code = static_cast(_response_code); + size_t size = _os.tellp(); + std::ostringstream header; + header << std::setw(3) << std::setfill('0') << code << " " // + << std::setw(11) << std::setfill(' ') << size << "\n"; + writeData(header); + } + writeData(_os); +} + +void OutputBuffer::writeData(std::ostringstream &os) { + // TODO(sp) This cruel and slightly non-portable hack avoids copying (which + // is important). We could do better by e.g. using boost::asio::streambuf. + struct Hack : public std::stringbuf { + [[nodiscard]] const char *base() const { return pbase(); } + }; + const char *buffer = static_cast(os.rdbuf())->base(); + size_t bytes_to_write = os.tellp(); + while (!shouldTerminate() && bytes_to_write > 0) { + Poller poller; + poller.addFileDescriptor(_fd, PollEvents::out); + int retval = poller.poll(std::chrono::milliseconds(100)); + if (retval > 0 && poller.isFileDescriptorSet(_fd, PollEvents::out)) { + ssize_t bytes_written = write(_fd, buffer, bytes_to_write); + if (bytes_written == -1) { + generic_error ge("could not write " + + std::to_string(bytes_to_write) + + " bytes to client socket"); + Informational(_logger) << ge; + break; + } + buffer += bytes_written; + bytes_to_write -= bytes_written; + } + } +} + +void OutputBuffer::setError(ResponseCode code, const std::string &message) { + Warning(_logger) << "error: " << message; + // only the first error is being returned + if (_error_message.empty()) { + _error_message = message + "\n"; + _response_code = code; + } +} diff --git a/src/OutputBuffer.h b/src/OutputBuffer.h new file mode 100644 index 0000000..34f7f47 --- /dev/null +++ b/src/OutputBuffer.h @@ -0,0 +1,73 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef OutputBuffer_h +#define OutputBuffer_h + +#include "config.h" // IWYU pragma: keep +#include +#include +class Logger; + +class OutputBuffer { +public: + // TODO(sp) Replace this plus its string message with std::error_code + enum class ResponseCode { + ok = 200, + invalid_header = 400, + not_found = 404, + limit_exceeded = 413, + incomplete_request = 451, + invalid_request = 452, + }; + + enum class ResponseHeader { off, fixed16 }; + + OutputBuffer(int fd, const bool &termination_flag, Logger *logger); + ~OutputBuffer(); + + bool shouldTerminate() const { return _termination_flag; } + + std::ostream &os() { return _os; } + + void setResponseHeader(ResponseHeader r) { _response_header = r; } + + void setError(ResponseCode code, const std::string &message); + + Logger *getLogger() const { return _logger; } + +private: + const int _fd; + const bool &_termination_flag; + Logger *const _logger; + std::ostringstream _os; + ResponseHeader _response_header; + ResponseCode _response_code; + std::string _error_message; + + void flush(); + void writeData(std::ostringstream &os); +}; + +#endif // OutputBuffer_h diff --git a/src/PerfdataAggregator.cc b/src/PerfdataAggregator.cc new file mode 100644 index 0000000..3a2e334 --- /dev/null +++ b/src/PerfdataAggregator.cc @@ -0,0 +1,71 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +// IWYU pragma: no_include +#include "PerfdataAggregator.h" +#include +#include +#include +#include +#include +#include +#include "Renderer.h" +#include "Row.h" +#include "StringColumn.h" +#include "contact_fwd.h" + +void PerfdataAggregator::consume(Row row, const contact * /* auth_user */, + std::chrono::seconds /* timezone_offset */) { + std::istringstream iss(_column->getValue(row)); + std::istream_iterator end; + for (auto it = std::istream_iterator(iss); it != end; ++it) { + auto pos = it->find('='); + if (pos != std::string::npos) { + try { + auto varname = it->substr(0, pos); + auto value = std::stod(it->substr(pos + 1)); + _aggregations.insert(std::make_pair(varname, _factory())) + .first->second->update(value); + } catch (const std::logic_error &e) { + } + } + } +} + +void PerfdataAggregator::output(RowRenderer &r) const { + std::string perf_data; + bool first = true; + for (const auto &entry : _aggregations) { + double value = entry.second->value(); + if (std::isfinite(value)) { + if (first) { + first = false; + } else { + perf_data += " "; + } + perf_data += entry.first + "=" + std::to_string(value); + } + } + r.output(perf_data); +} diff --git a/src/PerfdataAggregator.h b/src/PerfdataAggregator.h new file mode 100644 index 0000000..136d232 --- /dev/null +++ b/src/PerfdataAggregator.h @@ -0,0 +1,55 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef PerfdataAggregator_h +#define PerfdataAggregator_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include "Aggregator.h" +#include "Column.h" +#include "contact_fwd.h" +class Row; +class RowRenderer; +class StringColumn; + +class PerfdataAggregator : public Aggregator { +public: + PerfdataAggregator(AggregationFactory factory, const StringColumn *column) + : _factory(std::move(factory)), _column(column) {} + void consume(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) override; + void output(RowRenderer &r) const override; + +private: + AggregationFactory _factory; + const StringColumn *const _column; + std::map> _aggregations; +}; + +#endif // PerfdataAggregator_h diff --git a/src/Poller.h b/src/Poller.h new file mode 100644 index 0000000..296113f --- /dev/null +++ b/src/Poller.h @@ -0,0 +1,86 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2017 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Poller_h +#define Poller_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include "BitMask.h" + +enum class PollEvents { in = 1 << 0, out = 1 << 1, hup = 1 << 2 }; +IS_BIT_MASK(PollEvents); + +class Poller { +public: + template + int poll(std::chrono::duration timeout) { + int retval; + // I/O primitives can fail when interrupted by a signal, so we should + // retry the operation. In the plain C world, this is already + // encapsulated in e.g. glibc's TEMP_FAILURE_RETRY macro, see: + // https://www.gnu.org/software/libc/manual/html_node/Interrupted-Primitives.html + do { + auto millis = + std::chrono::duration_cast(timeout); + // The cast below is OK because int has at least 32 bits on all + // platforms we care about: The timeout is then limited to 24.85 + // days, which should be more than enough for our needs. + retval = ::poll(&_pollfds[0], _pollfds.size(), + static_cast(millis.count())); + } while (retval == -1 && errno == EINTR); + return retval; + } + + void addFileDescriptor(int fd, PollEvents e) { + _fd_to_pollfd[fd] = _pollfds.size(); + _pollfds.push_back({fd, toMask(e), 0}); + } + + bool isFileDescriptorSet(int fd, PollEvents e) const { + auto it = _fd_to_pollfd.find(fd); + return it != _fd_to_pollfd.end() && + (_pollfds[it->second].revents & toMask(e)) != 0; + } + +private: + std::vector _pollfds; + std::unordered_map _fd_to_pollfd; + + static short toMask(PollEvents e) { + // The cast below is OK because all POLLFOO values are within the + // guaranteed short value range. + return static_cast( + (is_empty_bit_mask(e & PollEvents::in) ? 0 : POLLIN) | + (is_empty_bit_mask(e & PollEvents::out) ? 0 : POLLOUT) | + (is_empty_bit_mask(e & PollEvents::hup) ? 0 : POLLHUP)); + } +}; + +#endif // Poller_h diff --git a/src/Query.cc b/src/Query.cc new file mode 100644 index 0000000..13877ee --- /dev/null +++ b/src/Query.cc @@ -0,0 +1,810 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Query.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Aggregator.h" +#include "AndingFilter.h" +#include "ChronoUtils.h" +#include "Column.h" +#include "Filter.h" +#include "Logger.h" +#include "MonitoringCore.h" +#include "NullColumn.h" +#include "OringFilter.h" +#include "OutputBuffer.h" +#include "StatsColumn.h" +#include "StringUtils.h" +#include "Table.h" +#include "Triggers.h" +#include "auth.h" +#include "opids.h" +#include "strutil.h" + +// for find_contact, ugly... +#ifdef CMC +#include "cmc.h" +#else +#include "nagios.h" +#endif + +namespace { +std::string nextStringArgument(char **line) { + if (auto value = next_field(line)) { + return value; + } + throw std::runtime_error("missing argument"); +} + +int nextNonNegativeIntegerArgument(char **line) { + auto value = nextStringArgument(line); + int number = atoi(value.c_str()); + if (isdigit(value[0]) == 0 || number < 0) { + throw std::runtime_error("expected non-negative integer"); + } + return number; +} + +void checkNoArguments(const char *line) { + if (line[0] != 0) { + throw std::runtime_error("superfluous argument(s)"); + } +} +} // namespace + +Query::Query(const std::list &lines, Table &table, + Encoding data_encoding, size_t max_response_size, + OutputBuffer &output, Logger *logger) + : _data_encoding(data_encoding) + , _max_response_size(max_response_size) + , _output(output) + , _renderer_query(nullptr) + , _table(table) + , _keepalive(false) + , _auth_user(nullptr) + , _wait_timeout(0) + , _wait_trigger(Triggers::Kind::all) + , _wait_object(nullptr) + , _separators("\n", ";", ",", "|") + , _show_column_headers(true) + , _output_format(OutputFormat::broken_csv) + , _limit(-1) + , _time_limit(-1) + , _time_limit_timeout(0) + , _current_line(0) + , _timezone_offset(0) + , _logger(logger) { + FilterStack filters; + FilterStack wait_conditions; + for (auto &line : lines) { + auto stripped_line = mk::rstrip(line); + if (stripped_line.empty()) { + break; + } + auto pos = stripped_line.find(':'); + std::string header; + std::string rest; + if (pos == std::string::npos) { + header = stripped_line; + } else { + header = stripped_line.substr(0, pos); + rest = mk::lstrip(stripped_line.substr(pos + 1)); + } + std::vector rest_copy(rest.begin(), rest.end()); + rest_copy.push_back('\0'); + char *arguments = &rest_copy[0]; + try { + if (header == "Filter") { + parseFilterLine(arguments, filters); + } else if (header == "Or") { + parseAndOrLine(arguments, Filter::Kind::row, OringFilter::make, + filters); + } else if (header == "And") { + parseAndOrLine(arguments, Filter::Kind::row, AndingFilter::make, + filters); + } else if (header == "Negate") { + parseNegateLine(arguments, filters); + } else if (header == "StatsOr") { + parseStatsAndOrLine(arguments, OringFilter::make); + } else if (header == "StatsAnd") { + parseStatsAndOrLine(arguments, AndingFilter::make); + } else if (header == "StatsNegate") { + parseStatsNegateLine(arguments); + } else if (header == "Stats") { + parseStatsLine(arguments); + } else if (header == "StatsGroupBy") { + parseStatsGroupLine(arguments); + } else if (header == "Columns") { + parseColumnsLine(arguments); + } else if (header == "ColumnHeaders") { + parseColumnHeadersLine(arguments); + } else if (header == "Limit") { + parseLimitLine(arguments); + } else if (header == "Timelimit") { + parseTimelimitLine(arguments); + } else if (header == "AuthUser") { + parseAuthUserHeader(arguments); + } else if (header == "Separators") { + parseSeparatorsLine(arguments); + } else if (header == "OutputFormat") { + parseOutputFormatLine(arguments); + } else if (header == "ResponseHeader") { + parseResponseHeaderLine(arguments); + } else if (header == "KeepAlive") { + parseKeepAliveLine(arguments); + } else if (header == "WaitCondition") { + parseFilterLine(arguments, wait_conditions); + } else if (header == "WaitConditionAnd") { + parseAndOrLine(arguments, Filter::Kind::wait_condition, + AndingFilter::make, wait_conditions); + } else if (header == "WaitConditionOr") { + parseAndOrLine(arguments, Filter::Kind::wait_condition, + OringFilter::make, wait_conditions); + } else if (header == "WaitConditionNegate") { + parseNegateLine(arguments, wait_conditions); + } else if (header == "WaitTrigger") { + parseWaitTriggerLine(arguments); + } else if (header == "WaitObject") { + parseWaitObjectLine(arguments); + } else if (header == "WaitTimeout") { + parseWaitTimeoutLine(arguments); + } else if (header == "Localtime") { + parseLocaltimeLine(arguments); + } else { + throw std::runtime_error("undefined request header"); + } + } catch (const std::runtime_error &e) { + _output.setError(OutputBuffer::ResponseCode::invalid_header, + header + ": " + e.what()); + } + } + + if (_columns.empty() && !doStats()) { + (void)table.any_column([this](std::shared_ptr c) { + return _columns.push_back(c), _all_columns.insert(c), false; + }); + // TODO(sp) We overwrite the value from a possible ColumnHeaders: line + // here, is that really what we want? + _show_column_headers = true; + } + + _filter = AndingFilter::make(Filter::Kind::row, std::move(filters)); + _wait_condition = AndingFilter::make(Filter::Kind ::wait_condition, + std::move(wait_conditions)); +} + +void Query::invalidRequest(const std::string &message) const { + _output.setError(OutputBuffer::ResponseCode::invalid_request, message); +} + +void Query::parseAndOrLine(char *line, Filter::Kind kind, + const LogicalConnective &connective, + FilterStack &filters) { + auto number = nextNonNegativeIntegerArgument(&line); + Filters subfilters; + for (auto i = 0; i < number; ++i) { + if (filters.empty()) { + throw std::runtime_error( + "error combining filters for table '" + _table.name() + + "': expected " + std::to_string(number) + + " filters, but only " + std::to_string(i) + " " + + (i == 1 ? "is" : "are") + " on stack"); + } + subfilters.push_back(std::move(filters.back())); + filters.pop_back(); + } + std::reverse(subfilters.begin(), subfilters.end()); + filters.push_back(connective(kind, std::move(subfilters))); +} + +void Query::parseNegateLine(char *line, FilterStack &filters) { + checkNoArguments(line); + if (filters.empty()) { + throw std::runtime_error( + "error combining filters for table '" + _table.name() + + "': expected 1 filters, but only 0 are on stack"); + } + + auto top = std::move(filters.back()); + filters.pop_back(); + filters.push_back(top->negate()); +} + +void Query::parseStatsAndOrLine(char *line, + const LogicalConnective &connective) { + auto number = nextNonNegativeIntegerArgument(&line); + Filters subfilters; + for (auto i = 0; i < number; ++i) { + if (_stats_columns.empty()) { + throw std::runtime_error( + "error combining filters for table '" + _table.name() + + "': expected " + std::to_string(number) + + " filters, but only " + std::to_string(i) + " " + + (i == 1 ? "is" : "are") + " on stack"); + } + subfilters.push_back(_stats_columns.back()->stealFilter()); + _stats_columns.pop_back(); + } + std::reverse(subfilters.begin(), subfilters.end()); + _stats_columns.push_back(std::make_unique( + connective(Filter::Kind::stats, std::move(subfilters)))); +} + +void Query::parseStatsNegateLine(char *line) { + checkNoArguments(line); + if (_stats_columns.empty()) { + throw std::runtime_error( + "error combining filters for table '" + _table.name() + + "': expected 1 filters, but only 0 are on stack"); + } + auto to_negate = _stats_columns.back()->stealFilter(); + _stats_columns.pop_back(); + _stats_columns.push_back( + std::make_unique(to_negate->negate())); +} + +namespace { +// NOTE: The suppressions below are necessary because cppcheck doesn't seem to +// understand default member initialization yet. :-/ + +// cppcheck-suppress noConstructor +class SumAggregation : public Aggregation { +public: + void update(double value) override { _sum += value; } + [[nodiscard]] double value() const override { return _sum; } + +private: + double _sum{0}; +}; + +// cppcheck-suppress noConstructor +class MinAggregation : public Aggregation { +public: + void update(double value) override { + if (_first || value < _sum) { + _sum = value; + } + _first = false; + } + + [[nodiscard]] double value() const override { return _sum; } + +private: + bool _first{true}; + // NOTE: This default is wrong, the neutral element for min is +Inf. Apart + // from being more consistent, using it would remove the need for _first. + double _sum{0}; +}; + +// cppcheck-suppress noConstructor +class MaxAggregation : public Aggregation { +public: + void update(double value) override { + if (_first || value > _sum) { + _sum = value; + } + _first = false; + } + + [[nodiscard]] double value() const override { return _sum; } + +private: + bool _first{true}; + // NOTE: This default is wrong, the neutral element for max is -Inf. Apart + // from being more consistent, using it would remove the need for _first. + double _sum{0}; +}; + +// cppcheck-suppress noConstructor +class AvgAggregation : public Aggregation { +public: + void update(double value) override { + _count++; + _sum += value; + } + + [[nodiscard]] double value() const override { return _sum / _count; } + +private: + std::uint32_t _count{0}; + double _sum{0}; +}; + +// cppcheck-suppress noConstructor +class StdAggregation : public Aggregation { +public: + void update(double value) override { + _count++; + _sum += value; + _sum_of_squares += value * value; + } + + [[nodiscard]] double value() const override { + auto mean = _sum / _count; + return sqrt(_sum_of_squares / _count - mean * mean); + } + +private: + std::uint32_t _count{0}; + double _sum{0}; + double _sum_of_squares{0}; +}; + +// cppcheck-suppress noConstructor +class SumInvAggregation : public Aggregation { +public: + void update(double value) override { _sum += 1.0 / value; } + [[nodiscard]] double value() const override { return _sum; } + +private: + double _sum{0}; +}; + +// cppcheck-suppress noConstructor +class AvgInvAggregation : public Aggregation { +public: + void update(double value) override { + _count++; + _sum += 1.0 / value; + } + + [[nodiscard]] double value() const override { return _sum / _count; } + +private: + std::uint32_t _count{0}; + double _sum{0}; +}; + +std::map stats_ops{ + {"sum", []() { return std::make_unique(); }}, + {"min", []() { return std::make_unique(); }}, + {"max", []() { return std::make_unique(); }}, + {"avg", []() { return std::make_unique(); }}, + {"std", []() { return std::make_unique(); }}, + {"suminv", []() { return std::make_unique(); }}, + {"avginv", []() { return std::make_unique(); }}}; +} // namespace + +void Query::parseStatsLine(char *line) { + // first token is either aggregation operator or column name + std::shared_ptr column; + std::unique_ptr sc; + auto col_or_op = nextStringArgument(&line); + auto it = stats_ops.find(col_or_op); + if (it == stats_ops.end()) { + column = _table.column(col_or_op); + auto relOp = relationalOperatorForName(nextStringArgument(&line)); + auto operand = mk::lstrip(line); + sc = std::make_unique( + column->createFilter(Filter::Kind::stats, relOp, operand)); + } else { + column = _table.column(nextStringArgument(&line)); + sc = std::make_unique(it->second, column.get()); + } + _stats_columns.push_back(std::move(sc)); + _all_columns.insert(column); + // Default to old behaviour: do not output column headers if we do Stats + // queries + _show_column_headers = false; +} + +void Query::parseFilterLine(char *line, FilterStack &filters) { + auto column = _table.column(nextStringArgument(&line)); + auto relOp = relationalOperatorForName(nextStringArgument(&line)); + auto operand = mk::lstrip(line); + auto sub_filter = column->createFilter(Filter::Kind::row, relOp, operand); + filters.push_back(std::move(sub_filter)); + _all_columns.insert(column); +} + +void Query::parseAuthUserHeader(char *line) { + _auth_user = find_contact(line); + if (_auth_user == nullptr) { + // Do not handle this as error any more. In a multi site setup + // not all users might be present on all sites by design. + _auth_user = unknown_auth_user(); + } +} + +void Query::parseStatsGroupLine(char *line) { + Warning(_logger) + << "Warning: StatsGroupBy is deprecated. Please use Columns instead."; + parseColumnsLine(line); +} + +void Query::parseColumnsLine(char *line) { + std::string str = line; + const std::string sep = " \t\n\v\f\r"; + for (auto pos = str.find_first_not_of(sep); pos != std::string::npos;) { + auto space = str.find_first_of(sep, pos); + auto column_name = + str.substr(pos, space - (space == std::string::npos ? 0 : pos)); + pos = str.find_first_not_of(sep, space); + std::shared_ptr column; + try { + column = _table.column(column_name); + } catch (const std::runtime_error &e) { + // Do not fail any longer. We might want to make this configurable. + // But not failing has the advantage that an updated GUI, that + // expects new columns, will be able to keep compatibility with + // older Livestatus versions. + Informational(_logger) + << "replacing non-existing column '" << column_name + << "' with null column, reason: " << e.what(); + column = std::make_shared( + column_name, "non-existing column", -1, -1, -1, 0); + } + _columns.push_back(column); + _all_columns.insert(column); + } + _show_column_headers = false; +} + +void Query::parseSeparatorsLine(char *line) { + std::string dsep = + std::string(1, char(nextNonNegativeIntegerArgument(&line))); + std::string fsep = + std::string(1, char(nextNonNegativeIntegerArgument(&line))); + std::string lsep = + std::string(1, char(nextNonNegativeIntegerArgument(&line))); + std::string hsep = + std::string(1, char(nextNonNegativeIntegerArgument(&line))); + _separators = CSVSeparators(dsep, fsep, lsep, hsep); +} + +namespace { +std::map formats{{"CSV", OutputFormat::csv}, + {"csv", OutputFormat::broken_csv}, + {"json", OutputFormat::json}, + {"python", OutputFormat::python}, + {"python3", OutputFormat::python3}}; +} // namespace + +void Query::parseOutputFormatLine(char *line) { + auto format_and_rest = mk::nextField(line); + auto it = formats.find(format_and_rest.first); + if (it == formats.end()) { + std::string msg; + for (const auto &entry : formats) { + msg += + std::string(msg.empty() ? "" : ", ") + "'" + entry.first + "'"; + } + throw std::runtime_error("missing/invalid output format, use one of " + + msg); + } + if (!mk::strip(format_and_rest.second).empty()) { + throw std::runtime_error("only 1 argument expected"); + } + _output_format = it->second; +} + +void Query::parseColumnHeadersLine(char *line) { + auto value = nextStringArgument(&line); + if (value == "on") { + _show_column_headers = true; + } else if (value == "off") { + _show_column_headers = false; + } else { + throw std::runtime_error("expected 'on' or 'off'"); + } +} + +void Query::parseKeepAliveLine(char *line) { + auto value = nextStringArgument(&line); + if (value == "on") { + _keepalive = true; + } else if (value == "off") { + _keepalive = false; + } else { + throw std::runtime_error("expected 'on' or 'off'"); + } +} + +void Query::parseResponseHeaderLine(char *line) { + auto value = nextStringArgument(&line); + if (value == "off") { + _output.setResponseHeader(OutputBuffer::ResponseHeader::off); + } else if (value == "fixed16") { + _output.setResponseHeader(OutputBuffer::ResponseHeader::fixed16); + } else { + throw std::runtime_error("expected 'off' or 'fixed16'"); + } +} + +void Query::parseLimitLine(char *line) { + _limit = nextNonNegativeIntegerArgument(&line); +} + +void Query::parseTimelimitLine(char *line) { + _time_limit = nextNonNegativeIntegerArgument(&line); + _time_limit_timeout = time(nullptr) + _time_limit; +} + +void Query::parseWaitTimeoutLine(char *line) { + _wait_timeout = + std::chrono::milliseconds(nextNonNegativeIntegerArgument(&line)); +} + +void Query::parseWaitTriggerLine(char *line) { + _wait_trigger = _table.core()->triggers().find(nextStringArgument(&line)); +} + +void Query::parseWaitObjectLine(char *line) { + auto objectspec = mk::lstrip(line); + _wait_object = _table.findObject(objectspec); + if (_wait_object.isNull()) { + throw std::runtime_error("object '" + objectspec + + "' not found or not supported by this table"); + } +} + +void Query::parseLocaltimeLine(char *line) { + auto value = nextNonNegativeIntegerArgument(&line); + // Compute offset to be *added* each time we output our time and + // *subtracted* from reference value by filter headers + auto diff = std::chrono::system_clock::from_time_t(value) - + std::chrono::system_clock::now(); + + // Round difference to half hour. We assume, that both clocks are more or + // less synchronized and that the time offset is only due to being in + // different time zones. This would be a one-liner if we already had C++17's + // std::chrono::round(). + using half_an_hour = std::chrono::duration>; + auto hah = std::chrono::duration_cast(diff); + auto rounded = half_an_hour(round(hah.count())); + auto offset = std::chrono::duration_cast(rounded); + if (offset <= std::chrono::hours(-24) || offset >= std::chrono::hours(24)) { + throw std::runtime_error( + "timezone difference greater than or equal to 24 hours"); + } + + if (offset != std::chrono::seconds(0)) { + using hour = std::chrono::duration>; + Debug(_logger) << "timezone offset is " + << std::chrono::duration_cast(offset).count() + << "h"; + } + _timezone_offset = offset; +} + +bool Query::doStats() const { return !_stats_columns.empty(); } + +bool Query::process() { + // Precondition: output has been reset + auto start_time = std::chrono::system_clock::now(); + auto renderer = + Renderer::make(_output_format, _output.os(), _output.getLogger(), + _separators, _data_encoding); + doWait(); + QueryRenderer q(*renderer, EmitBeginEnd::on); + _renderer_query = &q; + start(q); + _table.answerQuery(this); + finish(q); + auto elapsed = std::chrono::duration_cast( + std::chrono::system_clock::now() - start_time); + Informational(_logger) << "processed request in " << elapsed.count() + << " ms, replied with " << _output.os().tellp() + << " bytes"; + return _keepalive; +} + +void Query::start(QueryRenderer &q) { + if (_columns.empty()) { + getAggregatorsFor({}); + } + if (_show_column_headers) { + RowRenderer r(q); + for (const auto &column : _columns) { + r.output(column->name()); + } + + // Output dummy headers for stats columns + for (size_t col = 1; col <= _stats_columns.size(); ++col) { + r.output("stats_" + std::to_string(col)); + } + } +} + +bool Query::timelimitReached() const { + if (_time_limit >= 0 && time(nullptr) >= _time_limit_timeout) { + _output.setError(OutputBuffer::ResponseCode::limit_exceeded, + "Maximum query time of " + + std::to_string(_time_limit) + + " seconds exceeded!"); + return true; + } + return false; +} + +bool Query::processDataset(Row row) { + if (_output.shouldTerminate()) { + // Not the perfect response code, but good enough... + _output.setError(OutputBuffer::ResponseCode::limit_exceeded, + "core is shutting down"); + return false; + } + + if (static_cast(_output.os().tellp()) > _max_response_size) { + Warning(_logger) << "Maximum response size of " << _max_response_size + << " bytes exceeded!"; + // currently we only log an error into the log file and do + // not abort the query. We handle it like Limit: + return false; + } + + if (_filter->accepts(row, _auth_user, _timezone_offset) && + (_auth_user == nullptr || _table.isAuthorized(row, _auth_user))) { + _current_line++; + if (_limit >= 0 && static_cast(_current_line) > _limit) { + return false; + } + + // When we reach the time limit we let the query fail. Otherwise the + // user will not know that the answer is incomplete. + if (timelimitReached()) { + return false; + } + + if (doStats()) { + // Things get a bit tricky here: For stats queries, we have to + // combine rows with the same values in the non-stats columns. But + // when we finally output those non-stats columns in finish(), we + // don't have the row anymore, so we can't use Column::output() + // then. :-/ The slightly hacky workaround is to pre-render all + // non-stats columns into a single string here (RowFragment) and + // output it later in a verbatim manner. + std::ostringstream os; + { + auto renderer = + Renderer::make(_output_format, os, _output.getLogger(), + _separators, _data_encoding); + QueryRenderer q(*renderer, EmitBeginEnd::off); + RowRenderer r(q); + for (const auto &column : _columns) { + column->output(row, r, _auth_user, _timezone_offset); + } + } + for (const auto &aggr : getAggregatorsFor(RowFragment{os.str()})) { + aggr->consume(row, _auth_user, timezoneOffset()); + } + } else { + RowRenderer r(*_renderer_query); + for (const auto &column : _columns) { + column->output(row, r, _auth_user, _timezone_offset); + } + } + } + return true; +} + +void Query::finish(QueryRenderer &q) { + if (doStats()) { + for (const auto &group : _stats_groups) { + RowRenderer r(q); + if (!group.first._str.empty()) { + r.output(group.first); + } + for (const auto &aggr : group.second) { + aggr->output(r); + } + } + } +} + +std::unique_ptr Query::partialFilter( + const std::string &message, + std::function predicate) const { + auto result = _filter->partialFilter(std::move(predicate)); + Debug(_logger) << "partial filter for " << message << ": " << *result; + return result; +} + +std::optional Query::stringValueRestrictionFor( + const std::string &column_name) const { + auto result = _filter->stringValueRestrictionFor(column_name); + if (result) { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " is restricted to '" << *result << "'"; + } else { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " is unrestricted"; + } + return result; +} + +std::optional Query::greatestLowerBoundFor( + const std::string &column_name) const { + auto result = _filter->greatestLowerBoundFor(column_name, timezoneOffset()); + if (result) { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " has greatest lower bound " << *result << " (" + << FormattedTimePoint( + std::chrono::system_clock::from_time_t(*result)) + << ")"; + } else { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " has no greatest lower bound"; + } + return result; +} + +std::optional Query::leastUpperBoundFor( + const std::string &column_name) const { + auto result = _filter->leastUpperBoundFor(column_name, timezoneOffset()); + if (result) { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " has least upper bound " << *result << " (" + << FormattedTimePoint( + std::chrono::system_clock::from_time_t(*result)) + << ")"; + } else { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " has no least upper bound"; + } + return result; +} + +std::optional> Query::valueSetLeastUpperBoundFor( + const std::string &column_name) const { + auto result = + _filter->valueSetLeastUpperBoundFor(column_name, timezoneOffset()); + if (result) { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " has possible values " + << FormattedBitSet<32>{*result}; + } else { + Debug(_logger) << "column " << _table.name() << "." << column_name + << " has no value set restriction"; + } + return result; +} + +const std::vector> &Query::getAggregatorsFor( + const RowFragment &groupspec) { + auto it = _stats_groups.find(groupspec); + if (it == _stats_groups.end()) { + std::vector> aggrs; + for (const auto &sc : _stats_columns) { + aggrs.push_back(sc->createAggregator(_logger)); + } + it = _stats_groups.emplace(groupspec, move(aggrs)).first; + } + return it->second; +} + +void Query::doWait() { + _table.core()->triggers().wait_for(_wait_trigger, _wait_timeout, [this] { + return _wait_condition->accepts(_wait_object, _auth_user, + timezoneOffset()); + }); +} diff --git a/src/Query.h b/src/Query.h new file mode 100644 index 0000000..f86c5a8 --- /dev/null +++ b/src/Query.h @@ -0,0 +1,154 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Query_h +#define Query_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Filter.h" +#include "Renderer.h" +#include "RendererBrokenCSV.h" +#include "Row.h" +#include "StatsColumn.h" +#include "Triggers.h" +#include "contact_fwd.h" +#include "data_encoding.h" +class Aggregator; +class Column; +class Logger; +class OutputBuffer; +class Table; + +class Query { +public: + Query(const std::list &lines, Table &table, + Encoding data_encoding, size_t max_response_size, + OutputBuffer &output, Logger *logger); + + bool process(); + + // NOTE: We cannot make this 'const' right now, it increments _current_line + // and calls the non-const getAggregatorsFor() member function. + bool processDataset(Row row); + + bool timelimitReached() const; + void invalidRequest(const std::string &message) const; + + const contact *authUser() const { return _auth_user; } + std::chrono::seconds timezoneOffset() const { return _timezone_offset; } + + std::unique_ptr partialFilter( + const std::string &message, + std::function predicate) const; + std::optional stringValueRestrictionFor( + const std::string &column_name) const; + std::optional greatestLowerBoundFor( + const std::string &column_name) const; + std::optional leastUpperBoundFor( + const std::string &column_name) const; + std::optional> valueSetLeastUpperBoundFor( + const std::string &column_name) const; + + const std::unordered_set> &allColumns() const { + return _all_columns; + } + +private: + using LogicalConnective = + std::function(Filter::Kind, Filters)>; + + const Encoding _data_encoding; + const size_t _max_response_size; + OutputBuffer &_output; + QueryRenderer *_renderer_query; + Table &_table; + bool _keepalive; + using FilterStack = Filters; + std::unique_ptr _filter; + contact *_auth_user; + std::unique_ptr _wait_condition; + std::chrono::milliseconds _wait_timeout; + Triggers::Kind _wait_trigger; + Row _wait_object; + CSVSeparators _separators; + bool _show_column_headers; + OutputFormat _output_format; + int _limit; + int _time_limit; + time_t _time_limit_timeout; + unsigned _current_line; + std::chrono::seconds _timezone_offset; + Logger *const _logger; + std::vector> _columns; + std::vector> _stats_columns; + std::map>> + _stats_groups; + std::unordered_set> _all_columns; + + bool doStats() const; + void doWait(); + void parseFilterLine(char *line, FilterStack &filters); + void parseStatsLine(char *line); + void parseStatsGroupLine(char *line); + void parseAndOrLine(char *line, Filter::Kind kind, + const LogicalConnective &connective, + FilterStack &filters); + void parseNegateLine(char *line, FilterStack &filters); + void parseStatsAndOrLine(char *line, const LogicalConnective &connective); + void parseStatsNegateLine(char *line); + void parseColumnsLine(char *line); + void parseColumnHeadersLine(char *line); + void parseLimitLine(char *line); + void parseTimelimitLine(char *line); + void parseSeparatorsLine(char *line); + void parseOutputFormatLine(char *line); + void parseKeepAliveLine(char *line); + void parseResponseHeaderLine(char *line); + void parseAuthUserHeader(char *line); + void parseWaitTimeoutLine(char *line); + void parseWaitTriggerLine(char *line); + void parseWaitObjectLine(char *line); + void parseLocaltimeLine(char *line); + void start(QueryRenderer &q); + void finish(QueryRenderer &q); + + // NOTE: We cannot make this 'const' right now, it adds entries into + // _stats_groups. + const std::vector> &getAggregatorsFor( + const RowFragment &groupspec); +}; + +#endif // Query_h diff --git a/src/RegExp.cc b/src/RegExp.cc new file mode 100644 index 0000000..f613cba --- /dev/null +++ b/src/RegExp.cc @@ -0,0 +1,133 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "RegExp.h" + +#ifdef HAVE_RE2 +// ----------------------------------------------------------------------------- +// RE2 implementation +// ----------------------------------------------------------------------------- +#include +#include +#include + +class RegExp::Impl { +public: + Impl(const std::string &str, Case c, Syntax s) : _regex(str, opts(c, s)) { + if (!_regex.ok()) { + throw std::runtime_error(_regex.error()); + } + } + + std::string replace(std::string str, const std::string &replacement) { + RE2::GlobalReplace(&str, _regex, replacement); + return str; + } + + bool match(const std::string &str) const { + return RE2::FullMatch(str, _regex); + } + + bool search(const std::string &str) const { + return RE2::PartialMatch(str, _regex); + } + + static std::string engine() { return "RE2"; } + +private: + RE2 _regex; + + static RE2::Options opts(Case c, Syntax s) { + RE2::Options options{RE2::Quiet}; + options.set_case_sensitive(c == Case::respect); + options.set_literal(s == Syntax::literal); + return options; + } +}; + +#else +// ----------------------------------------------------------------------------- +// standard implementation +// ----------------------------------------------------------------------------- +#include +#include +#include +#include +class RegExp::Impl { +public: + Impl(const std::string &str, Case c, Syntax s) + : _regex(s == Syntax::literal + ? std::regex_replace( + str, std::regex(R"([.^$|()\[\]{}*+?\\])"), R"(\\&)", + std::regex_constants::format_sed) + : str, + c == Case::respect + ? std::regex::extended + : std::regex::extended | std::regex::icase) {} + + std::string replace(const std::string &str, + const std::string &replacement) { + return std::regex_replace(str, _regex, replacement, + std::regex_constants::format_sed); + } + + [[nodiscard]] bool match(const std::string &str) const { + return regex_match(str, _regex); + } + + [[nodiscard]] bool search(const std::string &str) const { + return regex_search(str, _regex); + } + + static std::string engine() { return "C++11"; } + +private: + std::regex _regex; +}; +#endif + +// ----------------------------------------------------------------------------- +// boilerplate pimpl code +// ----------------------------------------------------------------------------- + +RegExp::RegExp(const std::string &str, Case c, Syntax s) + : _impl(std::make_unique(str, c, s)) {} + +RegExp::~RegExp() = default; + +RegExp::RegExp(RegExp &&rhs) noexcept = default; + +RegExp &RegExp::operator=(RegExp &&rhs) noexcept = default; + +std::string RegExp::replace(const std::string &str, + const std::string &replacement) const { + return _impl->replace(str, replacement); +} + +bool RegExp::match(const std::string &str) const { return _impl->match(str); } + +bool RegExp::search(const std::string &str) const { return _impl->search(str); } + +// static +std::string RegExp::engine() { return Impl::engine(); } diff --git a/src/RegExp.h b/src/RegExp.h new file mode 100644 index 0000000..f5f8f3e --- /dev/null +++ b/src/RegExp.h @@ -0,0 +1,59 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef RegExp_h +#define RegExp_h + +#include "config.h" // IWYU pragma: keep +#include +#include + +class RegExp { +public: + enum class Case { ignore, respect }; + enum class Syntax { pattern, literal }; + + // Standard pimpl boileplate code, see Scott Meyer's "Effective Modern C++", + // item 22: "When using the Pimpl Idiom, define special member functions in + // the implementation file." + RegExp(const std::string &str, Case c, Syntax s); + ~RegExp(); + RegExp(const RegExp &rhs) = delete; + RegExp &operator=(const RegExp &rhs) = delete; + RegExp(RegExp &&rhs) noexcept; + RegExp &operator=(RegExp &&rhs) noexcept; + + [[nodiscard]] std::string replace(const std::string &str, + const std::string &replacement) const; + [[nodiscard]] bool match(const std::string &str) const; + [[nodiscard]] bool search(const std::string &str) const; + + static std::string engine(); + +private: + class Impl; + std::unique_ptr _impl; +}; + +#endif // RegExp_h diff --git a/src/Renderer.cc b/src/Renderer.cc new file mode 100644 index 0000000..4cc8d70 --- /dev/null +++ b/src/Renderer.cc @@ -0,0 +1,260 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Renderer.h" +#include +#include +#include +#include +#include "Logger.h" +#include "OStreamStateSaver.h" +#include "RendererBrokenCSV.h" +#include "RendererCSV.h" +#include "RendererJSON.h" +#include "RendererPython.h" +#include "RendererPython3.h" + +Renderer::Renderer(std::ostream &os, Logger *logger, Encoding data_encoding) + : _os(os), _data_encoding(data_encoding), _logger(logger) {} + +Renderer::~Renderer() = default; + +// static +std::unique_ptr Renderer::make(OutputFormat format, std::ostream &os, + Logger *logger, + const CSVSeparators &separators, + Encoding data_encoding) { + switch (format) { + case OutputFormat::csv: + return std::make_unique(os, logger, data_encoding); + case OutputFormat::broken_csv: + return std::make_unique(os, logger, separators, + data_encoding); + case OutputFormat::json: + return std::make_unique(os, logger, data_encoding); + case OutputFormat::python: + return std::make_unique(os, logger, data_encoding); + case OutputFormat::python3: + return std::make_unique(os, logger, data_encoding); + } + return nullptr; // unreachable +} + +void Renderer::output(double value) { + // Funny cast for older non-C++11 headers + if (static_cast(std::isnan(value))) { + output(Null()); + } else { + _os << value; + } +} + +void Renderer::output(PlainChar value) { _os.put(value._ch); } + +void Renderer::output(HexEscape value) { + OStreamStateSaver s(_os); + _os << R"(\x)" << std::hex << std::setw(2) << std::setfill('0') + << static_cast(static_cast(value._ch)); +} + +void Renderer::output(RowFragment value) { _os << value._str; } + +void Renderer::output(char16_t value) { + OStreamStateSaver s(_os); + _os << R"(\u)" << std::hex << std::setw(4) << std::setfill('0') << value; +} + +void Renderer::output(char32_t value) { + if (value < 0x10000) { + output(char16_t(value)); + } else { + // we need a surrogate pair + char32_t offs = value - 0x10000; + output(char16_t(((offs >> 10) & 0x3FF) + 0xD800)); + output(char16_t((offs & 0x3FF) + 0xDC00)); + } +} + +void Renderer::output(Null /* unused */) { outputNull(); } + +void Renderer::output(const std::vector &value) { outputBlob(value); } + +void Renderer::output(const std::string &value) { outputString(value); } + +void Renderer::output(std::chrono::system_clock::time_point value) { + output(std::chrono::system_clock::to_time_t(value)); +} + +namespace { +bool isBoringChar(unsigned char ch) { + return 32 <= ch && ch <= 127 && ch != '"' && ch != '\\'; +} + +} // namespace + +void Renderer::truncatedUTF8() { + Warning(_logger) << "UTF-8 sequence too short"; +} + +void Renderer::invalidUTF8(unsigned char ch) { + Warning(_logger) << "invalid byte " << int(ch) << " in UTF-8 sequence"; +} + +void Renderer::outputByteString(const std::string &prefix, + const std::vector &value) { + _os << prefix << R"(")"; // " + for (auto ch : value) { + if (isBoringChar(ch)) { + output(PlainChar{ch}); + } else { + output(HexEscape{ch}); + } + } + _os << R"(")"; // " +} + +void Renderer::outputUnicodeString(const std::string &prefix, const char *start, + const char *end, Encoding data_encoding) { + _os << prefix << R"(")"; // " + // TODO(sp) Use polymorphism instead of switch. + // TODO(sp) Use codecvt framework instead of homemade stuff. + switch (data_encoding) { + case Encoding::utf8: + outputUTF8(start, end); + break; + case Encoding::latin1: + outputLatin1(start, end); + break; + case Encoding::mixed: + outputMixed(start, end); + break; + } + _os << R"(")"; // " +} + +void Renderer::outputUTF8(const char *start, const char *end) { + for (const char *p = start; p != end; ++p) { + unsigned char ch0 = *p; + if ((ch0 & 0x80) == 0x00) { + if (isBoringChar(ch0)) { + output(PlainChar{*p}); + } else { + output(char32_t{ch0}); + } + } else if ((ch0 & 0xE0) == 0xC0) { + // 2 byte encoding + if (ch0 == 0xC0 || ch0 == 0xC1) { + // overlong encoding + return invalidUTF8(ch0); + } + if (end <= &p[1]) { + return truncatedUTF8(); + } + unsigned char ch1 = *++p; + if ((ch1 & 0xC0) != 0x80) { + return invalidUTF8(ch1); + } + output(char32_t(((ch0 & 0x1F) << 6) | // + ((ch1 & 0x3F) << 0))); + } else if ((ch0 & 0xF0) == 0xE0) { + // 3 byte encoding + if (end <= &p[2]) { + return truncatedUTF8(); + } + unsigned char ch1 = *++p; + if ((ch1 & 0xC0) != 0x80) { + return invalidUTF8(ch1); + } + unsigned char ch2 = *++p; + if ((ch2 & 0xC0) != 0x80) { + return invalidUTF8(ch2); + } + output(char32_t(((ch0 & 0x0F) << 12) | // + ((ch1 & 0x3F) << 6) | // + ((ch2 & 0x3F) << 0))); + } else if ((ch0 & 0xF8) == 0xF0) { + // 4 byte encoding + if (ch0 == 0xF5 || ch0 == 0xF6 || ch0 == 0xF7) { + // result would be larger than 0x10FFFF + return invalidUTF8(ch0); + } + if (end <= &p[3]) { + return truncatedUTF8(); + } + unsigned char ch1 = *++p; + if ((ch1 & 0xC0) != 0x80) { + return invalidUTF8(ch1); + } + unsigned char ch2 = *++p; + if ((ch2 & 0xC0) != 0x80) { + return invalidUTF8(ch2); + } + unsigned char ch3 = *++p; + if ((ch3 & 0xC0) != 0x80) { + return invalidUTF8(ch3); + } + output(char32_t(((ch0 & 0x07) << 18) | // + ((ch1 & 0x3F) << 12) | // + ((ch2 & 0x3f) << 6) | // + ((ch3 & 0x3f) << 0))); + } else { + return invalidUTF8(ch0); + } + } +} + +void Renderer::outputLatin1(const char *start, const char *end) { + for (const char *p = start; p != end; ++p) { + unsigned char ch = *p; + if (isBoringChar(ch)) { + output(PlainChar{*p}); + } else { + output(char32_t{ch}); + } + } +} + +void Renderer::outputMixed(const char *start, const char *end) { + for (const char *p = start; p != end; ++p) { + unsigned char ch0 = *p; + if (isBoringChar(ch0)) { + output(PlainChar{*p}); + } else if ((ch0 & 0xE0) == 0xC0) { + // Possible 2 byte encoding? => Assume UTF-8, ignore overlong + // encodings + if (end <= &p[1]) { + return truncatedUTF8(); + } + unsigned char ch1 = *++p; + if ((ch1 & 0xC0) != 0x80) { + return invalidUTF8(ch1); + } + output(char32_t(((ch0 & 0x1F) << 6) | // + ((ch1 & 0x3F) << 0))); + } else { + // Assume Latin1. + output(char32_t{ch0}); + } + } +} diff --git a/src/Renderer.h b/src/Renderer.h new file mode 100644 index 0000000..67496cb --- /dev/null +++ b/src/Renderer.h @@ -0,0 +1,341 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Renderer_h +#define Renderer_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include "data_encoding.h" +class CSVSeparators; +class Logger; + +enum class OutputFormat { csv, broken_csv, json, python, python3 }; + +struct Null {}; + +struct PlainChar { + char _ch; +}; + +struct HexEscape { + char _ch; +}; + +struct RowFragment { + std::string _str; + bool operator<(const RowFragment &other) const { return _str < other._str; } +}; + +class Renderer { +public: + static std::unique_ptr make(OutputFormat format, std::ostream &os, + Logger *logger, + const CSVSeparators &separators, + Encoding data_encoding); + + virtual ~Renderer(); + + // default implementation for (un)signed int/long + template + void output(T value) { + _os << std::to_string(value); + } + + void output(double value); + void output(PlainChar value); + void output(HexEscape value); + void output(RowFragment value); + void output(char16_t value); + void output(char32_t value); + void output(Null value); + void output(const std::vector &value); + void output(const std::string &value); + void output(std::chrono::system_clock::time_point value); + + // A whole query. + virtual void beginQuery() = 0; + virtual void separateQueryElements() = 0; + virtual void endQuery() = 0; + + // Output a single row returned by lq. + virtual void beginRow() = 0; + virtual void beginRowElement() = 0; + virtual void endRowElement() = 0; + virtual void separateRowElements() = 0; + virtual void endRow() = 0; + + // Output a list-valued column. + virtual void beginList() = 0; + virtual void separateListElements() = 0; + virtual void endList() = 0; + + // Output a list-valued value within a list-valued column. + virtual void beginSublist() = 0; + virtual void separateSublistElements() = 0; + virtual void endSublist() = 0; + + // Output a dictionary, see CustomVarsDictColumn. + virtual void beginDict() = 0; + virtual void separateDictElements() = 0; + virtual void separateDictKeyValue() = 0; + virtual void endDict() = 0; + +protected: + std::ostream &_os; + const Encoding _data_encoding; + + Renderer(std::ostream &os, Logger *logger, Encoding data_encoding); + + void outputByteString(const std::string &prefix, + const std::vector &value); + void outputUnicodeString(const std::string &prefix, const char *start, + const char *end, Encoding data_encoding); + +private: + Logger *const _logger; + + void outputUTF8(const char *start, const char *end); + void outputLatin1(const char *start, const char *end); + void outputMixed(const char *start, const char *end); + void truncatedUTF8(); + void invalidUTF8(unsigned char ch); + + virtual void outputNull() = 0; + virtual void outputBlob(const std::vector &value) = 0; + virtual void outputString(const std::string &value) = 0; +}; + +enum class EmitBeginEnd { on, off }; + +class QueryRenderer { +public: + class BeginEnd { + public: + explicit BeginEnd(QueryRenderer &query) : _query(query) { + if (_query._first) { + _query._first = false; + } else { + _query.renderer().separateQueryElements(); + } + } + + private: + QueryRenderer &_query; + }; + + QueryRenderer(Renderer &rend, EmitBeginEnd emitBeginEnd) + : _renderer(rend), _emitBeginEnd(emitBeginEnd), _first(true) { + if (_emitBeginEnd == EmitBeginEnd::on) { + renderer().beginQuery(); + } + } + + ~QueryRenderer() { + if (_emitBeginEnd == EmitBeginEnd::on) { + renderer().endQuery(); + } + } + + [[nodiscard]] Renderer &renderer() const { return _renderer; } + [[nodiscard]] EmitBeginEnd emitBeginEnd() const { return _emitBeginEnd; } + +private: + Renderer &_renderer; + EmitBeginEnd _emitBeginEnd; + bool _first; +}; + +class RowRenderer { +public: + class BeginEnd { + public: + explicit BeginEnd(RowRenderer &row) : _row(row) { + _row.separate(); + _row.renderer().beginRowElement(); + } + ~BeginEnd() { _row.renderer().endRowElement(); } + + private: + RowRenderer &_row; + }; + + explicit RowRenderer(QueryRenderer &query) + : _query(query), _be(query), _first(true) { + if (_query.emitBeginEnd() == EmitBeginEnd::on) { + renderer().beginRow(); + } + } + + ~RowRenderer() { + if (_query.emitBeginEnd() == EmitBeginEnd::on) { + renderer().endRow(); + } + } + + [[nodiscard]] Renderer &renderer() const { return _query.renderer(); } + + void output(RowFragment value) { + separate(); + renderer().output(std::move(value)); + } + + template + void output(T value) { + BeginEnd be(*this); + renderer().output(value); + } + +private: + QueryRenderer &_query; + QueryRenderer::BeginEnd _be; + bool _first; + + void separate() { + if (_first) { + _first = false; + } else { + renderer().separateRowElements(); + } + } +}; + +class ListRenderer { +public: + class BeginEnd { + public: + explicit BeginEnd(ListRenderer &list) : _list(list) { + if (_list._first) { + _list._first = false; + } else { + _list.renderer().separateListElements(); + } + } + + private: + ListRenderer &_list; + }; + + explicit ListRenderer(RowRenderer &row) + : _row(row), _be(row), _first(true) { + renderer().beginList(); + } + + ~ListRenderer() { renderer().endList(); } + + [[nodiscard]] Renderer &renderer() const { return _row.renderer(); } + + template + void output(T value) { + BeginEnd be(*this); + renderer().output(value); + } + +private: + RowRenderer &_row; + RowRenderer::BeginEnd _be; + bool _first; +}; + +class SublistRenderer { +public: + class BeginEnd { + public: + explicit BeginEnd(SublistRenderer &sublist) : _sublist(sublist) { + if (_sublist._first) { + _sublist._first = false; + } else { + _sublist.renderer().separateSublistElements(); + } + } + + private: + SublistRenderer &_sublist; + }; + + explicit SublistRenderer(ListRenderer &list) + : _list(list), _be(list), _first(true) { + renderer().beginSublist(); + } + + ~SublistRenderer() { renderer().endSublist(); } + + [[nodiscard]] Renderer &renderer() const { return _list.renderer(); } + + template + void output(T value) { + BeginEnd be(*this); + renderer().output(value); + } + +private: + ListRenderer &_list; + ListRenderer::BeginEnd _be; + bool _first; +}; + +class DictRenderer { +public: + class BeginEnd { + public: + explicit BeginEnd(DictRenderer &dict) : _dict(dict) { + if (_dict._first) { + _dict._first = false; + } else { + _dict.renderer().separateDictElements(); + } + } + + private: + DictRenderer &_dict; + }; + + explicit DictRenderer(RowRenderer &row) + : _row(row), _be(row), _first(true) { + renderer().beginDict(); + } + + ~DictRenderer() { renderer().endDict(); } + + [[nodiscard]] Renderer &renderer() const { return _row.renderer(); } + + void output(const std::string &key, const std::string &value) { + BeginEnd be(*this); + renderer().output(key); + renderer().separateDictKeyValue(); + renderer().output(value); + } + +private: + RowRenderer &_row; + RowRenderer::BeginEnd _be; + bool _first; +}; + +#endif // Renderer_h diff --git a/src/RendererBrokenCSV.cc b/src/RendererBrokenCSV.cc new file mode 100644 index 0000000..0993f15 --- /dev/null +++ b/src/RendererBrokenCSV.cc @@ -0,0 +1,73 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "RendererBrokenCSV.h" +#include + +// -------------------------------------------------------------------------- + +void RendererBrokenCSV::beginQuery() {} +void RendererBrokenCSV::separateQueryElements() {} +void RendererBrokenCSV::endQuery() {} + +// -------------------------------------------------------------------------- + +void RendererBrokenCSV::beginRow() {} +void RendererBrokenCSV::beginRowElement() {} +void RendererBrokenCSV::endRowElement() {} +void RendererBrokenCSV::separateRowElements() { _os << _separators.field(); } +void RendererBrokenCSV::endRow() { _os << _separators.dataset(); } + +// -------------------------------------------------------------------------- + +void RendererBrokenCSV::beginList() {} +void RendererBrokenCSV::separateListElements() { _os << _separators.list(); } +void RendererBrokenCSV::endList() {} + +// -------------------------------------------------------------------------- + +void RendererBrokenCSV::beginSublist() {} +void RendererBrokenCSV::separateSublistElements() { + _os << _separators.hostService(); +} +void RendererBrokenCSV::endSublist() {} + +// -------------------------------------------------------------------------- + +void RendererBrokenCSV::beginDict() {} +void RendererBrokenCSV::separateDictElements() { _os << _separators.list(); } +void RendererBrokenCSV::separateDictKeyValue() { + _os << _separators.hostService(); +} +void RendererBrokenCSV::endDict() {} + +// -------------------------------------------------------------------------- + +void RendererBrokenCSV::outputNull() {} + +void RendererBrokenCSV::outputBlob(const std::vector &value) { + _os.write(&value[0], value.size()); +} + +void RendererBrokenCSV::outputString(const std::string &value) { _os << value; } diff --git a/src/RendererBrokenCSV.h b/src/RendererBrokenCSV.h new file mode 100644 index 0000000..8dce29f --- /dev/null +++ b/src/RendererBrokenCSV.h @@ -0,0 +1,98 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef RendererBrokenCSV_h +#define RendererBrokenCSV_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "Renderer.h" +#include "data_encoding.h" +class Logger; + +class CSVSeparators { +public: + CSVSeparators(std::string dataset, std::string field, std::string list, + std::string host_service) + : _dataset(std::move(dataset)) + , _field(std::move(field)) + , _list(std::move(list)) + , _host_service(std::move(host_service)) {} + + [[nodiscard]] std::string dataset() const { return _dataset; } + [[nodiscard]] std::string field() const { return _field; } + [[nodiscard]] std::string list() const { return _list; } + [[nodiscard]] std::string hostService() const { return _host_service; } + +private: + std::string _dataset; + std::string _field; + std::string _list; + std::string _host_service; +}; + +// A broken CSV renderer, just for backwards compatibility with old Livestatus +// versions. +class RendererBrokenCSV : public Renderer { +public: + RendererBrokenCSV(std::ostream& os, Logger* logger, + CSVSeparators separators, Encoding data_encoding) + : Renderer(os, logger, data_encoding) + , _separators(std::move(separators)) {} + + void outputNull() override; + void outputBlob(const std::vector& value) override; + void outputString(const std::string& value) override; + + void beginQuery() override; + void separateQueryElements() override; + void endQuery() override; + + void beginRow() override; + void beginRowElement() override; + void endRowElement() override; + void separateRowElements() override; + void endRow() override; + + void beginList() override; + void separateListElements() override; + void endList() override; + + void beginSublist() override; + void separateSublistElements() override; + void endSublist() override; + + void beginDict() override; + void separateDictElements() override; + void separateDictKeyValue() override; + void endDict() override; + +private: + const CSVSeparators _separators; +}; + +#endif // RendererBrokenCSV_h diff --git a/src/RendererCSV.cc b/src/RendererCSV.cc new file mode 100644 index 0000000..db1bf42 --- /dev/null +++ b/src/RendererCSV.cc @@ -0,0 +1,84 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "RendererCSV.h" +#include +class Logger; + +RendererCSV::RendererCSV(std::ostream &os, Logger *logger, + Encoding data_encoding) + : Renderer(os, logger, data_encoding) {} + +// -------------------------------------------------------------------------- + +void RendererCSV::beginQuery() {} +void RendererCSV::separateQueryElements() {} +void RendererCSV::endQuery() {} + +// -------------------------------------------------------------------------- + +void RendererCSV::beginRow() {} +void RendererCSV::beginRowElement() { _os << R"(")"; } // " +void RendererCSV::endRowElement() { _os << R"(")"; } // " +void RendererCSV::separateRowElements() { _os << ","; } +void RendererCSV::endRow() { _os << "\r\n"; } + +// -------------------------------------------------------------------------- + +void RendererCSV::beginList() {} +void RendererCSV::separateListElements() { _os << ","; } +void RendererCSV::endList() {} + +// -------------------------------------------------------------------------- + +void RendererCSV::beginSublist() {} +void RendererCSV::separateSublistElements() { _os << "|"; } +void RendererCSV::endSublist() {} + +// -------------------------------------------------------------------------- + +void RendererCSV::beginDict() {} +void RendererCSV::separateDictElements() { _os << ","; } +void RendererCSV::separateDictKeyValue() { _os << "|"; } +void RendererCSV::endDict() {} + +// -------------------------------------------------------------------------- + +void RendererCSV::outputNull() {} + +void RendererCSV::outputEscaped(char ch) { + _os << (ch == '"' ? R"("")" : std::string(1, ch)); +} + +void RendererCSV::outputBlob(const std::vector &value) { + for (auto ch : value) { + outputEscaped(ch); + } +} + +void RendererCSV::outputString(const std::string &value) { + for (auto ch : value) { + outputEscaped(ch); + } +} diff --git a/src/RendererCSV.h b/src/RendererCSV.h new file mode 100644 index 0000000..8c16236 --- /dev/null +++ b/src/RendererCSV.h @@ -0,0 +1,73 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef RendererCSV_h +#define RendererCSV_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Renderer.h" +#include "data_encoding.h" +class Logger; + +// Note: The CSV format is a bit underspecified, but the most "authorative" +// reference seems to be https://tools.ietf.org/html/rfc4180. +class RendererCSV : public Renderer { +public: + RendererCSV(std::ostream &os, Logger *logger, Encoding data_encoding); + + void outputNull() override; + void outputBlob(const std::vector &value) override; + void outputString(const std::string &value) override; + + void beginQuery() override; + void separateQueryElements() override; + void endQuery() override; + + void beginRow() override; + void beginRowElement() override; + void endRowElement() override; + void separateRowElements() override; + void endRow() override; + + void beginList() override; + void separateListElements() override; + void endList() override; + + void beginSublist() override; + void separateSublistElements() override; + void endSublist() override; + + void beginDict() override; + void separateDictElements() override; + void separateDictKeyValue() override; + void endDict() override; + +private: + void outputEscaped(char ch); +}; + +#endif // RendererCSV_h diff --git a/src/RendererJSON.cc b/src/RendererJSON.cc new file mode 100644 index 0000000..cc9f963 --- /dev/null +++ b/src/RendererJSON.cc @@ -0,0 +1,80 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "RendererJSON.h" +#include +class Logger; + +RendererJSON::RendererJSON(std::ostream &os, Logger *logger, + Encoding data_encoding) + : Renderer(os, logger, data_encoding) {} + +// -------------------------------------------------------------------------- + +void RendererJSON::beginQuery() { _os << "["; } +void RendererJSON::separateQueryElements() { _os << ",\n"; } +void RendererJSON::endQuery() { _os << "]\n"; } + +// -------------------------------------------------------------------------- + +void RendererJSON::beginRow() { _os << "["; } +void RendererJSON::beginRowElement() {} +void RendererJSON::endRowElement() {} +void RendererJSON::separateRowElements() { _os << ","; } +void RendererJSON::endRow() { _os << "]"; } + +// -------------------------------------------------------------------------- + +void RendererJSON::beginList() { _os << "["; } +void RendererJSON::separateListElements() { _os << ","; } +void RendererJSON::endList() { _os << "]"; } + +// -------------------------------------------------------------------------- + +void RendererJSON::beginSublist() { beginList(); } +void RendererJSON::separateSublistElements() { separateListElements(); } +void RendererJSON::endSublist() { endList(); } + +// -------------------------------------------------------------------------- + +void RendererJSON::beginDict() { _os << "{"; } +void RendererJSON::separateDictElements() { _os << ","; } +void RendererJSON::separateDictKeyValue() { _os << ":"; } +void RendererJSON::endDict() { _os << "}"; } + +// -------------------------------------------------------------------------- + +void RendererJSON::outputNull() { _os << "null"; } + +void RendererJSON::outputBlob(const std::vector &value) { + // cppcheck is too dumb to see that we just take the address... :-/ + // cppcheck-suppress containerOutOfBoundsIndexExpression + outputUnicodeString("", &value[0], &value[value.size()], Encoding::latin1); +} + +void RendererJSON::outputString(const std::string &value) { + // cppcheck is too dumb to see that we just take the address... :-/ + // cppcheck-suppress containerOutOfBoundsIndexExpression + outputUnicodeString("", &value[0], &value[value.size()], _data_encoding); +} diff --git a/src/RendererJSON.h b/src/RendererJSON.h new file mode 100644 index 0000000..03a6722 --- /dev/null +++ b/src/RendererJSON.h @@ -0,0 +1,68 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef RendererJSON_h +#define RendererJSON_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Renderer.h" +#include "data_encoding.h" +class Logger; + +class RendererJSON : public Renderer { +public: + RendererJSON(std::ostream &os, Logger *logger, Encoding data_encoding); + + void outputNull() override; + void outputBlob(const std::vector &value) override; + void outputString(const std::string &value) override; + + void beginQuery() override; + void separateQueryElements() override; + void endQuery() override; + + void beginRow() override; + void beginRowElement() override; + void endRowElement() override; + void separateRowElements() override; + void endRow() override; + + void beginList() override; + void separateListElements() override; + void endList() override; + + void beginSublist() override; + void separateSublistElements() override; + void endSublist() override; + + void beginDict() override; + void separateDictElements() override; + void separateDictKeyValue() override; + void endDict() override; +}; + +#endif // RendererJSON_h diff --git a/src/RendererPython.cc b/src/RendererPython.cc new file mode 100644 index 0000000..18b991b --- /dev/null +++ b/src/RendererPython.cc @@ -0,0 +1,78 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "RendererPython.h" +#include +class Logger; + +RendererPython::RendererPython(std::ostream &os, Logger *logger, + Encoding data_encoding) + : Renderer(os, logger, data_encoding) {} + +// -------------------------------------------------------------------------- + +void RendererPython::beginQuery() { _os << "["; } +void RendererPython::separateQueryElements() { _os << ",\n"; } +void RendererPython::endQuery() { _os << "]\n"; } + +// -------------------------------------------------------------------------- + +void RendererPython::beginRow() { _os << "["; } +void RendererPython::beginRowElement() {} +void RendererPython::endRowElement() {} +void RendererPython::separateRowElements() { _os << ","; } +void RendererPython::endRow() { _os << "]"; } + +// -------------------------------------------------------------------------- + +void RendererPython::beginList() { _os << "["; } +void RendererPython::separateListElements() { _os << ","; } +void RendererPython::endList() { _os << "]"; } + +// -------------------------------------------------------------------------- + +void RendererPython::beginSublist() { beginList(); } +void RendererPython::separateSublistElements() { separateListElements(); } +void RendererPython::endSublist() { endList(); } + +// -------------------------------------------------------------------------- + +void RendererPython::beginDict() { _os << "{"; } +void RendererPython::separateDictElements() { _os << ","; } +void RendererPython::separateDictKeyValue() { _os << ":"; } +void RendererPython::endDict() { _os << "}"; } + +// -------------------------------------------------------------------------- + +void RendererPython::outputNull() { _os << "None"; } + +void RendererPython::outputBlob(const std::vector &value) { + outputByteString("", value); +} + +void RendererPython::outputString(const std::string &value) { + // cppcheck is too dumb to see that we just take the address... :-/ + // cppcheck-suppress containerOutOfBoundsIndexExpression + outputUnicodeString("u", &value[0], &value[value.size()], _data_encoding); +} diff --git a/src/RendererPython.h b/src/RendererPython.h new file mode 100644 index 0000000..eb927b9 --- /dev/null +++ b/src/RendererPython.h @@ -0,0 +1,68 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef RendererPython_h +#define RendererPython_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Renderer.h" +#include "data_encoding.h" +class Logger; + +class RendererPython : public Renderer { +public: + RendererPython(std::ostream &os, Logger *logger, Encoding data_encoding); + + void outputNull() override; + void outputBlob(const std::vector &value) override; + void outputString(const std::string &value) override; + + void beginQuery() override; + void separateQueryElements() override; + void endQuery() override; + + void beginRow() override; + void beginRowElement() override; + void endRowElement() override; + void separateRowElements() override; + void endRow() override; + + void beginList() override; + void separateListElements() override; + void endList() override; + + void beginSublist() override; + void separateSublistElements() override; + void endSublist() override; + + void beginDict() override; + void separateDictElements() override; + void separateDictKeyValue() override; + void endDict() override; +}; + +#endif // RendererPython_h diff --git a/src/RendererPython3.cc b/src/RendererPython3.cc new file mode 100644 index 0000000..33012fc --- /dev/null +++ b/src/RendererPython3.cc @@ -0,0 +1,78 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "RendererPython3.h" +#include +class Logger; + +RendererPython3::RendererPython3(std::ostream &os, Logger *logger, + Encoding data_encoding) + : Renderer(os, logger, data_encoding) {} + +// -------------------------------------------------------------------------- + +void RendererPython3::beginQuery() { _os << "["; } +void RendererPython3::separateQueryElements() { _os << ",\n"; } +void RendererPython3::endQuery() { _os << "]\n"; } + +// -------------------------------------------------------------------------- + +void RendererPython3::beginRow() { _os << "["; } +void RendererPython3::beginRowElement() {} +void RendererPython3::endRowElement() {} +void RendererPython3::separateRowElements() { _os << ","; } +void RendererPython3::endRow() { _os << "]"; } + +// -------------------------------------------------------------------------- + +void RendererPython3::beginList() { _os << "["; } +void RendererPython3::separateListElements() { _os << ","; } +void RendererPython3::endList() { _os << "]"; } + +// -------------------------------------------------------------------------- + +void RendererPython3::beginSublist() { beginList(); } +void RendererPython3::separateSublistElements() { separateListElements(); } +void RendererPython3::endSublist() { endList(); } + +// -------------------------------------------------------------------------- + +void RendererPython3::beginDict() { _os << "{"; } +void RendererPython3::separateDictElements() { _os << ","; } +void RendererPython3::separateDictKeyValue() { _os << ":"; } +void RendererPython3::endDict() { _os << "}"; } + +// -------------------------------------------------------------------------- + +void RendererPython3::outputNull() { _os << "None"; } + +void RendererPython3::outputBlob(const std::vector &value) { + outputByteString("b", value); +} + +void RendererPython3::outputString(const std::string &value) { + // cppcheck is too dumb to see that we just take the address... :-/ + // cppcheck-suppress containerOutOfBoundsIndexExpression + outputUnicodeString("", &value[0], &value[value.size()], _data_encoding); +} diff --git a/src/RendererPython3.h b/src/RendererPython3.h new file mode 100644 index 0000000..6c103a0 --- /dev/null +++ b/src/RendererPython3.h @@ -0,0 +1,68 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef RendererPython3_h +#define RendererPython3_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Renderer.h" +#include "data_encoding.h" +class Logger; + +class RendererPython3 : public Renderer { +public: + RendererPython3(std::ostream &os, Logger *logger, Encoding data_encoding); + + void outputNull() override; + void outputBlob(const std::vector &value) override; + void outputString(const std::string &value) override; + + void beginQuery() override; + void separateQueryElements() override; + void endQuery() override; + + void beginRow() override; + void beginRowElement() override; + void endRowElement() override; + void separateRowElements() override; + void endRow() override; + + void beginList() override; + void separateListElements() override; + void endList() override; + + void beginSublist() override; + void separateSublistElements() override; + void endSublist() override; + + void beginDict() override; + void separateDictElements() override; + void separateDictKeyValue() override; + void endDict() override; +}; + +#endif // RendererPython3_h diff --git a/src/Row.h b/src/Row.h new file mode 100644 index 0000000..97a2b6a --- /dev/null +++ b/src/Row.h @@ -0,0 +1,47 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Row_h +#define Row_h + +#include "config.h" // IWYU pragma: keep + +class Row { +public: + // Here we basically forget the actual type of the row... + explicit Row(const void *ptr) : _ptr(ptr) {} + + // ... and here we reconstruct it, hopefully in a correct way. :-/ + template + [[nodiscard]] const T *rawData() const { + return static_cast(_ptr); + } + + [[nodiscard]] bool isNull() const { return _ptr == nullptr; } + +private: + const void *_ptr; +}; + +#endif // Row_h diff --git a/src/ServiceContactsColumn.cc b/src/ServiceContactsColumn.cc new file mode 100644 index 0000000..5f7f55d --- /dev/null +++ b/src/ServiceContactsColumn.cc @@ -0,0 +1,60 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ServiceContactsColumn.h" +#include "Row.h" + +#ifdef CMC +#include "ContactList.h" +#include "Object.h" +#include "cmc.h" +#else +#include +#include "nagios.h" +#endif + +std::vector ServiceContactsColumn::getValue( + Row row, const contact* /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { +#ifdef CMC + if (auto object = columnData(row)) { + return object->_contact_list->contactNames(); + } + return {}; +#else + std::unordered_set names; + if (auto svc = columnData(row)) { + for (auto cm = svc->contacts; cm != nullptr; cm = cm->next) { + names.insert(cm->contact_ptr->name); + } + for (auto cgm = svc->contact_groups; cgm != nullptr; cgm = cgm->next) { + for (auto cm = cgm->group_ptr->members; cm != nullptr; + cm = cm->next) { + names.insert(cm->contact_ptr->name); + } + } + } + return std::vector(names.begin(), names.end()); +#endif +} diff --git a/src/ServiceContactsColumn.h b/src/ServiceContactsColumn.h new file mode 100644 index 0000000..0e30d01 --- /dev/null +++ b/src/ServiceContactsColumn.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ServiceContactsColumn_h +#define ServiceContactsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class Row; + +class ServiceContactsColumn : public ListColumn { +public: + ServiceContactsColumn(const std::string& name, + const std::string& description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + std::vector getValue( + Row row, const contact* auth_user, + std::chrono::seconds timezone_offset) const override; +}; + +#endif // ServiceContactsColumn_h diff --git a/src/ServiceGroupMembersColumn.cc b/src/ServiceGroupMembersColumn.cc new file mode 100644 index 0000000..e91e230 --- /dev/null +++ b/src/ServiceGroupMembersColumn.cc @@ -0,0 +1,126 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ServiceGroupMembersColumn.h" +#include +#include +#include +#include "Filter.h" +#include "ListFilter.h" +#include "Logger.h" +#include "Renderer.h" +#include "Row.h" + +#ifdef CMC +#include +#include "Host.h" +#include "LogEntry.h" +#include "Service.h" +#include "State.h" +#else +#include "auth.h" +#endif + +void ServiceGroupMembersColumn::output( + Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + ListRenderer l(r); + for (const auto &member : getMembers(row, auth_user)) { + SublistRenderer s(l); + s.output(member.host_name); + s.output(member.description); + if (_show_state) { + s.output(static_cast(member.current_state)); + s.output(static_cast(member.has_been_checked)); + } + } +} + +namespace { +// value must be of the form +// hostname hostservice_separator service_description +std::string checkValue(Logger *logger, RelationalOperator relOp, + const std::string &value) { + auto pos = value.find(ServiceGroupMembersColumn::separator()); + bool equality = relOp == RelationalOperator::equal || + relOp == RelationalOperator::not_equal; + if (pos == std::string::npos && !(equality && value.empty())) { + Informational(logger) + << "Invalid reference value for service list membership. Must be 'hostname" + << ServiceGroupMembersColumn::separator() << "servicename'"; + } + return value; +} +} // namespace + +std::unique_ptr ServiceGroupMembersColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, + checkValue(logger(), relOp, value)); +} + +std::vector ServiceGroupMembersColumn::getValue( + Row row, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + auto members = getMembers(row, auth_user); + std::vector specnames; + std::transform(members.begin(), members.end(), + std::back_inserter(specnames), [](const auto &member) { + return member.host_name + separator() + + member.description; + }); + return specnames; +} + +std::vector +ServiceGroupMembersColumn::getMembers(Row row, const contact *auth_user) const { + std::vector members; +#ifdef CMC + if (auto p = columnData(row)) { + for (auto &svc : *p) { + if (auth_user == nullptr || svc->hasContact(_mc, auth_user)) { + members.emplace_back( + svc->host()->name(), svc->name(), + static_cast(svc->state()->_current_state), + svc->state()->_has_been_checked); + } + } + } +#else + if (auto p = columnData(row)) { + for (servicesmember *mem = *p; mem != nullptr; mem = mem->next) { + service *svc = mem->service_ptr; + if (auth_user == nullptr || + is_authorized_for(_mc, auth_user, svc->host_ptr, svc)) { + members.emplace_back( + svc->host_name, svc->description, + static_cast(svc->current_state), + svc->has_been_checked != 0); + } + } + } +#endif + return members; +} diff --git a/src/ServiceGroupMembersColumn.h b/src/ServiceGroupMembersColumn.h new file mode 100644 index 0000000..35fb31a --- /dev/null +++ b/src/ServiceGroupMembersColumn.h @@ -0,0 +1,93 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ServiceGroupMembersColumn_h +#define ServiceGroupMembersColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include "Filter.h" +#include "ListColumn.h" +#include "opids.h" +class MonitoringCore; +class Row; +class RowRenderer; +enum class ServiceState; + +#ifdef CMC +#include "cmc.h" +#else +#include "nagios.h" +#endif + +class ServiceGroupMembersColumn : public ListColumn { +public: + ServiceGroupMembersColumn(const std::string &name, + const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, + MonitoringCore *mc, bool show_state) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _show_state(show_state) {} + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + static std::string separator() { return ""; } + +private: + MonitoringCore *_mc; + bool _show_state; + + struct Member { + Member(std::string hn, std::string d, ServiceState cs, bool hbc) + : host_name(std::move(hn)) + , description(std::move(d)) + , current_state(cs) + , has_been_checked(hbc) {} + + std::string host_name; + std::string description; + ServiceState current_state; + bool has_been_checked; + }; + + std::vector getMembers(Row row, const contact *auth_user) const; +}; + +#endif // ServiceGroupMembersColumn_h diff --git a/src/ServiceGroupsColumn.cc b/src/ServiceGroupsColumn.cc new file mode 100644 index 0000000..af7451f --- /dev/null +++ b/src/ServiceGroupsColumn.cc @@ -0,0 +1,60 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ServiceGroupsColumn.h" +#include "Row.h" + +#ifdef CMC +#include "Object.h" +#include "ObjectGroup.h" +#include "cmc.h" +#else +#include "auth.h" +#include "nagios.h" +#endif + +std::vector ServiceGroupsColumn::getValue( + Row row, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + std::vector group_names; +#ifdef CMC + if (auto object = columnData(row)) { + for (const auto &og : object->_groups) { + if (og->isContactAuthorized(_mc, auth_user)) { + group_names.push_back(og->name()); + } + } + } +#else + if (auto p = columnData(row)) { + for (objectlist *list = *p; list != nullptr; list = list->next) { + auto sg = static_cast(list->object_ptr); + if (is_authorized_for_service_group(_mc, sg, auth_user)) { + group_names.emplace_back(sg->group_name); + } + } + } +#endif + return group_names; +} diff --git a/src/ServiceGroupsColumn.h b/src/ServiceGroupsColumn.h new file mode 100644 index 0000000..f715a7e --- /dev/null +++ b/src/ServiceGroupsColumn.h @@ -0,0 +1,54 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ServiceGroupsColumn_h +#define ServiceGroupsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "ListColumn.h" +#include "contact_fwd.h" +class MonitoringCore; +class Row; + +class ServiceGroupsColumn : public ListColumn { +public: + ServiceGroupsColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, MonitoringCore *mc) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) {} + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *const _mc; +}; + +#endif // ServiceGroupsColumn_h diff --git a/src/ServiceListColumn.cc b/src/ServiceListColumn.cc new file mode 100644 index 0000000..d4d9ae8 --- /dev/null +++ b/src/ServiceListColumn.cc @@ -0,0 +1,145 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ServiceListColumn.h" +#include +#include +#include "Renderer.h" +#include "Row.h" + +#ifdef CMC +#include +#include +#include +#include "Host.h" +#include "LogEntry.h" +#include "Service.h" +#include "State.h" +#include "Timeperiod.h" +#else +#include +#include "TimeperiodsCache.h" +#include "auth.h" +#endif + +void ServiceListColumn::output(Row row, RowRenderer &r, + const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + ListRenderer l(r); + for (const auto &entry : getEntries(row, auth_user)) { + if (_info_depth == 0) { + l.output(std::string(entry.description)); + } else { + SublistRenderer s(l); + s.output(entry.description); + if (_info_depth >= 1) { + s.output(static_cast(entry.current_state)); + s.output(static_cast(entry.has_been_checked)); + } + if (_info_depth >= 2) { + s.output(entry.plugin_output); + } + if (_info_depth >= 3) { + s.output(static_cast(entry.last_hard_state)); + s.output(entry.current_attempt); + s.output(entry.max_check_attempts); + s.output(entry.scheduled_downtime_depth); + s.output(static_cast(entry.acknowledged)); + s.output(static_cast(entry.service_period_active)); + } + } + } +} + +std::vector ServiceListColumn::getValue( + Row row, const contact *auth_user, + std::chrono::seconds /*timezone_offset*/) const { + auto entries = getEntries(row, auth_user); + std::vector descriptions; + std::transform(entries.begin(), entries.end(), + std::back_inserter(descriptions), + [](const auto &entry) { return entry.description; }); + return descriptions; +} + +#ifndef CMC +extern TimeperiodsCache *g_timeperiods_cache; + +namespace { +bool inCustomTimeperiod(service *svc) { + for (customvariablesmember *cvm = svc->custom_variables; cvm != nullptr; + cvm = cvm->next) { + if (strcmp(cvm->variable_name, "SERVICE_PERIOD") == 0) { + return g_timeperiods_cache->inTimeperiod(cvm->variable_value); + } + } + return true; // assume 24X7 +} +} // namespace +#endif + +std::vector ServiceListColumn::getEntries( + Row row, const contact *auth_user) const { + std::vector entries; +#ifdef CMC + if (auto mem = columnData(row)) { + for (auto &svc : *mem) { + if (auth_user == nullptr || svc->hasContact(_mc, auth_user)) { + entries.emplace_back( + svc->name(), + static_cast(svc->state()->_current_state), + svc->state()->_has_been_checked, + svc->state()->_plugin_output, + static_cast(svc->state()->_last_hard_state), + svc->state()->_current_attempt, svc->_max_check_attempts, + svc->state()->_scheduled_downtime_depth, + svc->state()->_acknowledged, + svc->_service_period->isActive()); + } + } + } +#else + if (auto p = columnData(row)) { + for (servicesmember *mem = *p; mem != nullptr; mem = mem->next) { + service *svc = mem->service_ptr; + if (auth_user == nullptr || + is_authorized_for(_mc, auth_user, svc->host_ptr, svc)) { + entries.emplace_back( + svc->description, + static_cast(svc->current_state), + svc->has_been_checked != 0, + svc->plugin_output == nullptr + ? "" + : std::string(svc->plugin_output), + static_cast(svc->last_hard_state), + svc->current_attempt, svc->max_attempts, + svc->scheduled_downtime_depth, + svc->problem_has_been_acknowledged != 0, + inCustomTimeperiod(svc)); + } + } + } +#endif + return entries; +} diff --git a/src/ServiceListColumn.h b/src/ServiceListColumn.h new file mode 100644 index 0000000..5f857ad --- /dev/null +++ b/src/ServiceListColumn.h @@ -0,0 +1,98 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ServiceListColumn_h +#define ServiceListColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include "ListColumn.h" +class MonitoringCore; +class Row; +class RowRenderer; +enum class ServiceState; + +#ifdef CMC +#include "cmc.h" +#else +#include "nagios.h" +#endif + +class ServiceListColumn : public ListColumn { +public: + ServiceListColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset, MonitoringCore *mc, + int info_depth) + : ListColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _info_depth(info_depth) {} + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + std::vector getValue( + Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + +private: + MonitoringCore *_mc; + int _info_depth; + + struct Entry { + Entry(std::string d, ServiceState cs, bool hbc, std::string po, + ServiceState lhs, uint32_t ca, uint32_t mca, uint32_t sdt, bool a, + bool spa) + : description(std::move(d)) + , current_state(cs) + , has_been_checked(hbc) + , plugin_output(std::move(po)) + , last_hard_state(lhs) + , current_attempt(ca) + , max_check_attempts(mca) + , scheduled_downtime_depth(sdt) + , acknowledged(a) + , service_period_active(spa) {} + + std::string description; + ServiceState current_state; + bool has_been_checked; + std::string plugin_output; + ServiceState last_hard_state; + uint32_t current_attempt; + uint32_t max_check_attempts; + uint32_t scheduled_downtime_depth; + bool acknowledged; + bool service_period_active; + }; + + std::vector getEntries(Row row, const contact *auth_user) const; +}; + +#endif // ServiceListColumn_h diff --git a/src/ServiceListStateColumn.cc b/src/ServiceListStateColumn.cc new file mode 100644 index 0000000..2fe98b7 --- /dev/null +++ b/src/ServiceListStateColumn.cc @@ -0,0 +1,121 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ServiceListStateColumn.h" +#include "LogEntry.h" +#include "Row.h" + +#ifdef CMC +#include +#include "Service.h" +#include "State.h" +#else +#include "auth.h" +#endif + +int32_t ServiceListStateColumn::getValue(Row row, + const contact *auth_user) const { +#ifdef CMC + if (auto p = columnData(row)) { + return getValueFromServices(_mc, _logictype, p, auth_user); + } + return 0; +#else + servicesmember *mem = nullptr; + if (auto p = columnData(row)) { + mem = *p; + } + return getValueFromServices(_mc, _logictype, mem, auth_user); +#endif +} + +// static +int32_t ServiceListStateColumn::getValueFromServices(MonitoringCore *mc, + Type logictype, + service_list mem, + const contact *auth_user) { + int32_t result = 0; +#ifdef CMC + if (mem != nullptr) { + for (const auto &svc : *mem) { + if (auth_user == nullptr || svc->hasContact(mc, auth_user)) { + update(logictype, svc.get(), result); + } + } + } +#else + for (; mem != nullptr; mem = mem->next) { + service *svc = mem->service_ptr; + if (auth_user == nullptr || + is_authorized_for(mc, auth_user, svc->host_ptr, svc)) { + update(logictype, svc, result); + } + } +#endif + return result; +} + +// static +void ServiceListStateColumn::update(Type logictype, service *svc, + int32_t &result) { +#ifdef CMC + uint32_t last_hard_state = svc->state()->_last_hard_state; + uint32_t current_state = svc->state()->_current_state; + bool has_been_checked = svc->state()->_has_been_checked; +#else + int last_hard_state = svc->last_hard_state; + int current_state = svc->current_state; + bool has_been_checked = svc->has_been_checked != 0; +#endif + int service_state; + Type lt; + if (static_cast(logictype) >= 60) { + service_state = last_hard_state; + lt = static_cast(static_cast(logictype) - 64); + } else { + service_state = current_state; + lt = logictype; + } + switch (lt) { + case Type::worst_state: + if (worse(static_cast(service_state), + static_cast(result))) { + result = service_state; + } + break; + case Type::num: + result++; + break; + case Type::num_pending: + if (!has_been_checked) { + result++; + } + break; + default: + if (has_been_checked && service_state == static_cast(lt)) { + result++; + } + break; + } +} diff --git a/src/ServiceListStateColumn.h b/src/ServiceListStateColumn.h new file mode 100644 index 0000000..23d5557 --- /dev/null +++ b/src/ServiceListStateColumn.h @@ -0,0 +1,88 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ServiceListStateColumn_h +#define ServiceListStateColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +class MonitoringCore; +class Row; + +#ifdef CMC +#include "Host.h" +#include "cmc.h" +#else +#include "nagios.h" +#endif + +class ServiceListStateColumn : public IntColumn { +public: + // TODO(sp) Remove the magic arithmetic + enum class Type { + num_ok = 0, + num_warn = 1, + num_crit = 2, + num_unknown = 3, + num_pending = 4, + worst_state = -2, + num_hard_ok = (0 + 64), + num_hard_warn = (1 + 64), + num_hard_crit = (2 + 64), + num_hard_unknown = (3 + 64), + worst_hard_state = (-2 + 64), + num = -1 + }; + + ServiceListStateColumn(const std::string &name, + const std::string &description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset, + MonitoringCore *mc, Type logictype) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _logictype(logictype) {} + + int32_t getValue(Row row, const contact *auth_user) const override; + +#ifdef CMC + using service_list = const Host::services_t *; +#else + using service_list = servicesmember *; +#endif + + static int32_t getValueFromServices(MonitoringCore *mc, Type logictype, + service_list mem, + const contact *auth_user); + +private: + MonitoringCore *_mc; + const Type _logictype; + + static void update(Type logictype, service *svc, int32_t &result); +}; + +#endif // ServiceListStateColumn_h diff --git a/src/ServiceSpecialDoubleColumn.cc b/src/ServiceSpecialDoubleColumn.cc new file mode 100644 index 0000000..ec6b388 --- /dev/null +++ b/src/ServiceSpecialDoubleColumn.cc @@ -0,0 +1,86 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ServiceSpecialDoubleColumn.h" +#include "Row.h" + +#ifdef CMC +#include "HostSpecialDoubleColumn.h" +class Object; +#else +#include +#include +#include "nagios.h" +#endif + +double ServiceSpecialDoubleColumn::getValue(Row row) const { +#ifdef CMC + if (auto object = columnData(row)) { + switch (_type) { + case Type::staleness: + return HostSpecialDoubleColumn::staleness(object); + } + } +#else + if (auto svc = columnData(row)) { + switch (_type) { + case Type::staleness: { + extern int interval_length; + auto check_result_age = + static_cast(time(nullptr) - svc->last_check); + if (svc->check_interval != 0) { + return check_result_age / + (svc->check_interval * interval_length); + } + + // check_mk PASSIVE CHECK without check interval uses the check + // interval of its check-mk service + bool is_cmk_passive = + strncmp(svc->check_command_ptr->name, "check_mk-", 9) == 0; + if (is_cmk_passive) { + host *host = svc->host_ptr; + for (servicesmember *svc_member = host->services; + svc_member != nullptr; svc_member = svc_member->next) { + service *tmp_svc = svc_member->service_ptr; + if (strncmp(tmp_svc->check_command_ptr->name, + "check-mk", 9) == 0) { + return check_result_age / + ((tmp_svc->check_interval == 0 + ? 1 + : tmp_svc->check_interval) * + interval_length); + } + } + // Shouldn't happen! We always expect a check-mk service + return 1; + } + // Other non-cmk passive and active checks without + // check_interval + return check_result_age / interval_length; + } + } + } +#endif + return 0; +} diff --git a/src/ServiceSpecialDoubleColumn.h b/src/ServiceSpecialDoubleColumn.h new file mode 100644 index 0000000..58a86d4 --- /dev/null +++ b/src/ServiceSpecialDoubleColumn.h @@ -0,0 +1,51 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ServiceSpecialDoubleColumn_h +#define ServiceSpecialDoubleColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "DoubleColumn.h" +class Row; + +class ServiceSpecialDoubleColumn : public DoubleColumn { +public: + enum class Type { staleness }; + + ServiceSpecialDoubleColumn(const std::string& name, + const std::string& description, int indirect, + int extra_offset, int extra_extra_offset, + int offset, Type ssdc_type) + : DoubleColumn(name, description, indirect, extra_offset, + extra_extra_offset, offset) + , _type(ssdc_type) {} + + [[nodiscard]] double getValue(Row row) const override; + +private: + const Type _type; +}; + +#endif // ServiceSpecialDoubleColumn_h diff --git a/src/ServiceSpecialIntColumn.cc b/src/ServiceSpecialIntColumn.cc new file mode 100644 index 0000000..cf043a5 --- /dev/null +++ b/src/ServiceSpecialIntColumn.cc @@ -0,0 +1,82 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "ServiceSpecialIntColumn.h" +#include "Row.h" + +#ifdef CMC +#include "Core.h" +#include "MonitoringCore.h" +#include "Object.h" +#include "RRDBackend.h" +#include "RRDInfoCache.h" +#include "State.h" +#include "cmc.h" +#else +#include "nagios.h" +#include "pnp4nagios.h" +#endif + +int32_t ServiceSpecialIntColumn::getValue( + Row row, const contact* /* auth_user */) const { +#ifdef CMC + if (auto object = columnData(row)) { + switch (_type) { + case Type::real_hard_state: { + if (object->isCurrentStateOK()) { + return 0; + } + auto state = object->state(); + return state->_state_type == StateType::hard + ? state->_current_state + : state->_last_hard_state; + } + case Type::pnp_graph_present: + return _mc->impl() + ->_rrd_backend.infoFor(object) + ._names.empty() + ? 0 + : 1; + } + } +#else + if (auto svc = columnData(row)) { + switch (_type) { + case Type::real_hard_state: + if (svc->current_state == 0) { + return 0; + } + if (svc->state_type == HARD_STATE) { + return svc->current_state; + } + return svc->last_hard_state; + + case Type::pnp_graph_present: + return pnpgraph_present(_mc, svc->host_ptr->name, + svc->description); + } + } +#endif + return 0; +} diff --git a/src/ServiceSpecialIntColumn.h b/src/ServiceSpecialIntColumn.h new file mode 100644 index 0000000..82c028d --- /dev/null +++ b/src/ServiceSpecialIntColumn.h @@ -0,0 +1,56 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef ServiceSpecialIntColumn_h +#define ServiceSpecialIntColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +#include "contact_fwd.h" +class MonitoringCore; +class Row; + +class ServiceSpecialIntColumn : public IntColumn { +public: + enum class Type { real_hard_state, pnp_graph_present }; + + ServiceSpecialIntColumn(const std::string &name, + const std::string &description, int indirect_offset, + int extra_offset, int extra_extra_offset, + int offset, MonitoringCore *mc, Type ssic_type) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _type(ssic_type) {} + + int32_t getValue(Row row, const contact *auth_user) const override; + +private: + MonitoringCore *_mc; + const Type _type; +}; + +#endif // ServiceSpecialIntColumn_h diff --git a/src/StatsColumn.cc b/src/StatsColumn.cc new file mode 100644 index 0000000..71766e3 --- /dev/null +++ b/src/StatsColumn.cc @@ -0,0 +1,67 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "StatsColumn.h" +#include +#include +#include +#include "Aggregator.h" +#include "AndingFilter.h" +#include "Column.h" +#include "CountAggregator.h" +#include "Filter.h" +#include "Logger.h" + +StatsColumnCount::StatsColumnCount(std::unique_ptr filter) + : _filter(std::move(filter)) {} + +std::unique_ptr StatsColumnCount::stealFilter() { + return std::move(_filter); +} + +std::unique_ptr StatsColumnCount::createAggregator( + Logger * /*logger*/) const { + return std::make_unique(_filter.get()); +} + +// Note: We create an "accept all" filter, just in case we fall back to +// counting. +StatsColumnOp::StatsColumnOp(AggregationFactory factory, Column *column) + : _factory(std::move(factory)) + , _column(column) + , _filter(AndingFilter::make(Filter::Kind::stats, Filters())) {} + +std::unique_ptr StatsColumnOp::stealFilter() { + throw std::runtime_error("not a counting aggregator"); +} + +std::unique_ptr StatsColumnOp::createAggregator( + Logger *logger) const { + try { + return _column->createAggregator(_factory); + } catch (const std::runtime_error &e) { + Informational(logger) << e.what() << ", falling back to counting"; + return std::make_unique(_filter.get()); + } +} diff --git a/src/StatsColumn.h b/src/StatsColumn.h new file mode 100644 index 0000000..c18bf95 --- /dev/null +++ b/src/StatsColumn.h @@ -0,0 +1,65 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef StatsColumn_h +#define StatsColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Column.h" +#include "Filter.h" +class Aggregator; +class Logger; + +class StatsColumn { +public: + virtual ~StatsColumn() = default; + virtual std::unique_ptr stealFilter() = 0; + virtual std::unique_ptr createAggregator( + Logger *logger) const = 0; +}; + +class StatsColumnCount : public StatsColumn { +public: + explicit StatsColumnCount(std::unique_ptr filter); + std::unique_ptr stealFilter() override; + std::unique_ptr createAggregator(Logger *logger) const override; + +private: + std::unique_ptr _filter; +}; + +class StatsColumnOp : public StatsColumn { +public: + StatsColumnOp(AggregationFactory factory, Column *column); + std::unique_ptr stealFilter() override; + std::unique_ptr createAggregator(Logger *logger) const override; + +private: + AggregationFactory _factory; + Column *_column; + std::unique_ptr _filter; +}; + +#endif // StatsColumn_h diff --git a/src/StatusSpecialIntColumn.cc b/src/StatusSpecialIntColumn.cc new file mode 100644 index 0000000..fe7d091 --- /dev/null +++ b/src/StatusSpecialIntColumn.cc @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "StatusSpecialIntColumn.h" +#include "MonitoringCore.h" +#include "Row.h" +#include "mk_inventory.h" +#include "nagios.h" + +int32_t StatusSpecialIntColumn::getValue(Row /* row */, + const contact* /* auth_user */) const { + switch (_type) { + case Type::mk_inventory_last: + // Check_MK Inventory touches the file ".last" after each inventory + return static_cast( + mk_inventory_last(_mc->mkInventoryPath() + "/.last")); + case Type::num_queued_notifications: + return static_cast(_mc->numQueuedNotifications()); + case Type::num_queued_alerts: + return static_cast(_mc->numQueuedAlerts()); + } + // never reached, make -Wall happy + return 0; +} diff --git a/src/StatusSpecialIntColumn.h b/src/StatusSpecialIntColumn.h new file mode 100644 index 0000000..c923a97 --- /dev/null +++ b/src/StatusSpecialIntColumn.h @@ -0,0 +1,59 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef StatusSpecialIntColumn_h +#define StatusSpecialIntColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +#include "contact_fwd.h" +class MonitoringCore; +class Row; + +class StatusSpecialIntColumn : public IntColumn { +public: + enum class Type { + mk_inventory_last, + num_queued_notifications, + num_queued_alerts + }; + + StatusSpecialIntColumn(const std::string& name, + const std::string& description, int indirect_offset, + int extra_offset, int extra_extra_offset, int offset, + MonitoringCore* mc, Type type) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) + , _mc(mc) + , _type(type) {} + int32_t getValue(Row row, const contact* auth_user) const override; + +private: + MonitoringCore* _mc; + const Type _type; +}; + +#endif // StatusSpecialIntColumn_h diff --git a/src/Store.cc b/src/Store.cc new file mode 100644 index 0000000..f168f69 --- /dev/null +++ b/src/Store.cc @@ -0,0 +1,311 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Store.h" +#include +#include +#include +#include +#include +#include +#include +#include "Aggregator.h" // IWYU pragma: keep +#include "DowntimeOrComment.h" // IWYU pragma: keep +#include "EventConsoleConnection.h" +#include "InputBuffer.h" +#include "LogEntry.h" // IWYU pragma: keep +#include "Logger.h" +#include "MonitoringCore.h" +#include "OutputBuffer.h" +#include "Query.h" +#include "StringUtils.h" +#include "Table.h" +#include "mk_logwatch.h" + +Store::Store(MonitoringCore *mc) + : _mc(mc) + , _log_cache(mc, mc->maxCachedMessages()) + , _table_columns(mc) + , _table_commands(mc) + , _table_comments(mc) + , _table_contactgroups(mc) + , _table_contacts(mc) + , _table_downtimes(mc) + , _table_eventconsoleevents(mc) + , _table_eventconsolehistory(mc) + , _table_eventconsolereplication(mc) + , _table_eventconsolerules(mc) + , _table_eventconsolestatus(mc) + , _table_hostgroups(mc) + , _table_hosts(mc) + , _table_hostsbygroup(mc) + , _table_log(mc, &_log_cache) + , _table_servicegroups(mc) + , _table_services(mc) + , _table_servicesbygroup(mc) + , _table_servicesbyhostgroup(mc) + , _table_statehistory(mc, &_log_cache) + , _table_status(mc) + , _table_timeperiods(mc) + , _table_dummy(mc) { + addTable(_table_columns); + addTable(_table_commands); + addTable(_table_comments); + addTable(_table_contactgroups); + addTable(_table_contacts); + addTable(_table_downtimes); + addTable(_table_hostgroups); + addTable(_table_hostsbygroup); + addTable(_table_hosts); + addTable(_table_log); + addTable(_table_servicegroups); + addTable(_table_servicesbygroup); + addTable(_table_servicesbyhostgroup); + addTable(_table_services); + addTable(_table_statehistory); + addTable(_table_status); + addTable(_table_timeperiods); + addTable(_table_eventconsoleevents); + addTable(_table_eventconsolehistory); + addTable(_table_eventconsolestatus); + addTable(_table_eventconsolereplication); + addTable(_table_eventconsolerules); +} + +void Store::addTable(Table &table) { + _tables.emplace(table.name(), &table); + _table_columns.addTable(table); +} + +Table &Store::findTable(OutputBuffer &output, const std::string &name) { + // NOTE: Even with an invalid table name we continue, so we can parse + // headers, especially ResponseHeader. + if (name.empty()) { + output.setError(OutputBuffer::ResponseCode::invalid_request, + "Invalid GET request, missing table name"); + return _table_dummy; + } + auto it = _tables.find(name); + if (it == _tables.end()) { + output.setError(OutputBuffer::ResponseCode::not_found, + "Invalid GET request, no such table '" + name + "'"); + return _table_dummy; + } + return *it->second; +} + +void Store::registerDowntime(nebstruct_downtime_data *data) { + _downtimes.registerDowntime(data); +} + +void Store::registerComment(nebstruct_comment_data *data) { + _comments.registerComment(data); +} + +namespace { +std::list getLines(InputBuffer &input) { + std::list lines; + while (!input.empty()) { + lines.push_back(input.nextLine()); + if (lines.back().empty()) { + break; + } + } + return lines; +} +} // namespace + +void Store::logRequest(const std::string &line, + const std::list &lines) { + Informational log(logger()); + log << "request: " << line; + if (logger()->isLoggable(LogLevel::debug)) { + for (const auto &l : lines) { + log << R"(\n)" << l; + } + } else { + size_t s = lines.size(); + if (s > 0) { + log << R"(\n{)" << s << (s == 1 ? " line follows" : " lines follow") + << "...}"; + } + } +} + +Store::ExternalCommand::ExternalCommand(const std::string &str) { + constexpr int timestamp_len = 10; + constexpr int prefix_len = timestamp_len + 3; + if (str.size() <= prefix_len || str[0] != '[' || + str[prefix_len - 2] != ']' || str[prefix_len - 1] != ' ') { + throw std::invalid_argument("malformed timestamp in command '" + str + + "'"); + } + auto semi = str.find(';', prefix_len); + _prefix = str.substr(0, prefix_len); + _name = str.substr(prefix_len, semi - prefix_len); + _arguments = semi == std::string::npos ? "" : str.substr(semi); +} + +Store::ExternalCommand Store::ExternalCommand::withName( + const std::string &name) const { + return ExternalCommand(_prefix, name, _arguments); +} + +std::string Store::ExternalCommand::str() const { + return _prefix + _name + _arguments; +} + +std::vector Store::ExternalCommand::args() const { + if (_arguments.empty()) { + return {}; + } + return mk::split(_arguments.substr(1), ';'); +} + +bool Store::answerRequest(InputBuffer &input, OutputBuffer &output) { + // Precondition: output has been reset + InputBuffer::Result res = input.readRequest(); + if (res != InputBuffer::Result::request_read) { + if (res != InputBuffer::Result::eof) { + std::ostringstream os; + os << "client connection terminated: " << res; + output.setError(OutputBuffer::ResponseCode::incomplete_request, + os.str()); + } + return false; + } + std::string line = input.nextLine(); + if (mk::starts_with(line, "GET ")) { + auto lines = getLines(input); + logRequest(line, lines); + return answerGetRequest(lines, output, mk::lstrip(line.substr(4))); + } + if (mk::starts_with(line, "GET")) { + // only to get error message + auto lines = getLines(input); + logRequest(line, lines); + return answerGetRequest(lines, output, ""); + } + if (mk::starts_with(line, "COMMAND ")) { + logRequest(line, {}); + try { + answerCommandRequest(ExternalCommand(mk::lstrip(line.substr(8)))); + } catch (const std::invalid_argument &err) { + Warning(logger()) << err.what(); + } + return true; + } + if (mk::starts_with(line, "LOGROTATE")) { + logRequest(line, {}); + Informational(logger()) << "Forcing logfile rotation"; + rotate_log_file(time(nullptr)); + schedule_new_event(EVENT_LOG_ROTATION, 1, get_next_log_rotation_time(), + 0, 0, + reinterpret_cast(get_next_log_rotation_time), + 1, nullptr, nullptr, 0); + return false; + } + logRequest(line, {}); + Warning(logger()) << "Invalid request '" << line << "'"; + output.setError(OutputBuffer::ResponseCode::invalid_request, + "Invalid request method"); + return false; +} + +void Store::answerCommandRequest(const ExternalCommand &command) { + if (command.name() == "MK_LOGWATCH_ACKNOWLEDGE") { + answerCommandMkLogwatchAcknowledge(command); + return; + } + if (mk::starts_with(command.name(), "EC_")) { + answerCommandEventConsole(command); + return; + } + // Nagios doesn't have a LOG command, so we map it to the custom command + // _LOG, which we implement for ourselves. + answerCommandNagios(command.name() == "LOG" ? command.withName("_LOG") + : command); +} + +void Store::answerCommandMkLogwatchAcknowledge(const ExternalCommand &command) { + // COMMAND [1462191638] MK_LOGWATCH_ACKNOWLEDGE;host123;\var\log\syslog + auto args = command.args(); + if (args.size() != 2) { + Warning(logger()) << "MK_LOGWATCH_ACKNOWLEDGE expects 2 arguments"; + return; + } + mk_logwatch_acknowledge(logger(), _mc->mkLogwatchPath(), args[0], args[1]); +} + +namespace { +class ECTableConnection : public EventConsoleConnection { +public: + ECTableConnection(Logger *logger, std::string path, std::string command) + : EventConsoleConnection(logger, move(path)) + , _command(std::move(command)) {} + +private: + void sendRequest(std::ostream &os) override { os << _command; } + void receiveReply(std::istream & /*is*/) override {} + std::string _command; +}; +} // namespace + +void Store::answerCommandEventConsole(const ExternalCommand &command) { + if (!_mc->mkeventdEnabled()) { + Notice(logger()) << "event console disabled, ignoring command '" + << command.str() << "'"; + return; + } + try { + ECTableConnection( + logger(), _mc->mkeventdSocketPath(), + "COMMAND " + command.name().substr(3) + command.arguments()) + .run(); + } catch (const std::runtime_error &err) { + Alert(logger()) << err.what(); + } +} + +void Store::answerCommandNagios(const ExternalCommand &command) { + std::lock_guard lg(_command_mutex); + auto command_str = command.str(); + // The Nagios headers are (once again) not const-correct... + auto cmd = const_cast(command_str.c_str()); +#ifdef NAGIOS4 + process_external_command1(cmd); +#else + submit_external_command(cmd, nullptr); +#endif +} + +bool Store::answerGetRequest(const std::list &lines, + OutputBuffer &output, + const std::string &tablename) { + return Query(lines, findTable(output, tablename), _mc->dataEncoding(), + _mc->maxResponseSize(), output, logger()) + .process(); +} + +Logger *Store::logger() const { return _mc->loggerLivestatus(); } diff --git a/src/Store.h b/src/Store.h new file mode 100644 index 0000000..52b3814 --- /dev/null +++ b/src/Store.h @@ -0,0 +1,199 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Store_h +#define Store_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#ifndef CMC +#include +#include +#endif +#include "LogCache.h" +#include "Table.h" +#include "TableColumns.h" +#include "TableCommands.h" +#include "TableComments.h" +#include "TableContactGroups.h" +#include "TableContacts.h" +#include "TableDowntimes.h" +#include "TableEventConsoleEvents.h" +#include "TableEventConsoleHistory.h" +#include "TableEventConsoleReplication.h" +#include "TableEventConsoleRules.h" +#include "TableEventConsoleStatus.h" +#include "TableHostGroups.h" +#include "TableHosts.h" +#include "TableHostsByGroup.h" +#include "TableLog.h" +#include "TableServiceGroups.h" +#include "TableServices.h" +#include "TableServicesByGroup.h" +#include "TableServicesByHostGroup.h" +#include "TableStateHistory.h" +#include "TableStatus.h" +#include "TableTimeperiods.h" +class Query; +class InputBuffer; +class Logger; +class MonitoringCore; +class OutputBuffer; + +#ifdef CMC +#include +#include "TableCachedStatehist.h" +class GlobalConfig; +class Object; +#else +#include +#include "DowntimesOrComments.h" +#include "nagios.h" +#endif + +class Store { +public: + explicit Store(MonitoringCore *mc); +#ifdef CMC + LogCache *logCache() { return &_log_cache; }; + bool answerRequest(InputBuffer *, OutputBuffer *); + bool answerGetRequest(const std::list &lines, + OutputBuffer &output, const std::string &tablename); + void answerCommandRequest(const char *command, Logger *logger); + void setMaxCachedMessages(unsigned long m); + void switchStatehistTable(); + void buildStatehistCache(); + void flushStatehistCache(); + void tryFinishStatehistCache(); + bool addObjectHistcache(Object *object); + void addAlertToStatehistCache(Object *object, int state, + const char *output); + void addDowntimeToStatehistCache(Object *object, bool started); + void addFlappingToStatehistCache(Object *object, bool started); +#else + bool answerRequest(InputBuffer &input, OutputBuffer &output); + + void registerDowntime(nebstruct_downtime_data *data); + void registerComment(nebstruct_comment_data *data); +#endif + [[nodiscard]] Logger *logger() const; + +private: + struct TableDummy : public Table { + explicit TableDummy(MonitoringCore *mc) : Table(mc) {} + [[nodiscard]] std::string name() const override { return "dummy"; } + [[nodiscard]] std::string namePrefix() const override { + return "dummy_"; + } + void answerQuery(Query * /*unused*/) override {} + }; + + MonitoringCore *_mc; +#ifndef CMC + // TODO(sp) These fields should better be somewhere else, e.g. module.cc +public: + DowntimesOrComments _downtimes; + DowntimesOrComments _comments; + +private: +#endif + LogCache _log_cache; + +#ifdef CMC + TableCachedStatehist _table_cached_statehist; +#endif + TableColumns _table_columns; + TableCommands _table_commands; + TableComments _table_comments; + TableContactGroups _table_contactgroups; + TableContacts _table_contacts; + TableDowntimes _table_downtimes; + TableEventConsoleEvents _table_eventconsoleevents; + TableEventConsoleHistory _table_eventconsolehistory; + TableEventConsoleReplication _table_eventconsolereplication; + TableEventConsoleRules _table_eventconsolerules; + TableEventConsoleStatus _table_eventconsolestatus; + TableHostGroups _table_hostgroups; + TableHosts _table_hosts; + TableHostsByGroup _table_hostsbygroup; + TableLog _table_log; + TableServiceGroups _table_servicegroups; + TableServices _table_services; + TableServicesByGroup _table_servicesbygroup; + TableServicesByHostGroup _table_servicesbyhostgroup; + TableStateHistory _table_statehistory; + TableStatus _table_status; + TableTimeperiods _table_timeperiods; + TableDummy _table_dummy; + + std::map _tables; + +#ifndef CMC + // Nagios is not thread-safe, so this mutex protects calls to + // process_external_command1 / submit_external_command. + std::mutex _command_mutex; +#endif + + void addTable(Table &table); + Table &findTable(OutputBuffer &output, const std::string &name); +#ifdef CMC + const GlobalConfig *config() const; + uint32_t horizon() const; +#else + void logRequest(const std::string &line, + const std::list &lines); + bool answerGetRequest(const std::list &lines, + OutputBuffer &output, const std::string &tablename); + + class ExternalCommand { + public: + explicit ExternalCommand(const std::string &str); + [[nodiscard]] ExternalCommand withName(const std::string &name) const; + [[nodiscard]] std::string name() const { return _name; } + [[nodiscard]] std::string arguments() const { return _arguments; } + [[nodiscard]] std::string str() const; + [[nodiscard]] std::vector args() const; + + private: + std::string _prefix; // including brackets and space + std::string _name; + std::string _arguments; + + ExternalCommand(std::string prefix, std::string name, + std::string arguments) + : _prefix(std::move(prefix)) + , _name(std::move(name)) + , _arguments(std::move(arguments)) {} + }; + + void answerCommandRequest(const ExternalCommand &command); + void answerCommandMkLogwatchAcknowledge(const ExternalCommand &command); + void answerCommandEventConsole(const ExternalCommand &command); + void answerCommandNagios(const ExternalCommand &command); +#endif +}; + +#endif // Store_h diff --git a/src/StringColumn.cc b/src/StringColumn.cc new file mode 100644 index 0000000..a91170f --- /dev/null +++ b/src/StringColumn.cc @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "StringColumn.h" +#include +#include "Filter.h" +#include "Renderer.h" +#include "Row.h" +#include "StringFilter.h" + +void StringColumn::output(Row row, RowRenderer &r, + const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const { + r.output(row.isNull() ? "" : getValue(row)); +} + +std::unique_ptr StringColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, value); +} + +std::unique_ptr StringColumn::createAggregator( + AggregationFactory /*factory*/) const { + throw std::runtime_error("aggregating on string column '" + name() + + "' not supported"); +} diff --git a/src/StringColumn.h b/src/StringColumn.h new file mode 100644 index 0000000..52e5ec2 --- /dev/null +++ b/src/StringColumn.h @@ -0,0 +1,65 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef StringColumn_h +#define StringColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class StringColumn : public Column { +public: + StringColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset) + : Column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] ColumnType type() const override { + return ColumnType::string; + } + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; + + [[nodiscard]] virtual std::string getValue(Row row) const = 0; +}; + +#endif // StringColumn_h diff --git a/src/StringFilter.cc b/src/StringFilter.cc new file mode 100644 index 0000000..40a36fa --- /dev/null +++ b/src/StringFilter.cc @@ -0,0 +1,97 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "StringFilter.h" +#include "Filter.h" +#include "RegExp.h" +#include "Row.h" +#include "StringColumn.h" + +StringFilter::StringFilter(Kind kind, const StringColumn &column, + RelationalOperator relOp, const std::string &value) + : ColumnFilter(kind, column, relOp, value) + , _column(column) + , _regExp(makeRegExpFor(relOp, value)) {} + +bool StringFilter::accepts(Row row, const contact * /* auth_user */, + std::chrono::seconds /* timezone_offset */) const { + std::string act_string = _column.getValue(row); + switch (oper()) { + case RelationalOperator::equal: + case RelationalOperator::equal_icase: + return _regExp->match(act_string); + case RelationalOperator::not_equal: + case RelationalOperator::not_equal_icase: + return !_regExp->match(act_string); + case RelationalOperator::matches: + case RelationalOperator::matches_icase: + return _regExp->search(act_string); + case RelationalOperator::doesnt_match: + case RelationalOperator::doesnt_match_icase: + return !_regExp->search(act_string); + // FIXME: The cases below are nonsense for UTF-8... + case RelationalOperator::less: + return act_string < value(); + case RelationalOperator::greater_or_equal: + return act_string >= value(); + case RelationalOperator::greater: + return act_string > value(); + case RelationalOperator::less_or_equal: + return act_string <= value(); + } + return false; // unreachable +} + +std::optional StringFilter::stringValueRestrictionFor( + const std::string &column_name) const { + if (column_name != columnName()) { + return {}; // wrong column + } + switch (oper()) { + case RelationalOperator::equal: + return {value()}; + case RelationalOperator::not_equal: + case RelationalOperator::matches: + case RelationalOperator::doesnt_match: + case RelationalOperator::equal_icase: + case RelationalOperator::not_equal_icase: + case RelationalOperator::matches_icase: + case RelationalOperator::doesnt_match_icase: + case RelationalOperator::less: + case RelationalOperator::greater_or_equal: + case RelationalOperator::greater: + case RelationalOperator::less_or_equal: + return {}; + } + return {}; // unreachable +} + +std::unique_ptr StringFilter::copy() const { + return std::make_unique(*this); +} + +std::unique_ptr StringFilter::negate() const { + return std::make_unique( + kind(), _column, negateRelationalOperator(oper()), value()); +} diff --git a/src/StringFilter.h b/src/StringFilter.h new file mode 100644 index 0000000..df5e66a --- /dev/null +++ b/src/StringFilter.h @@ -0,0 +1,57 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef StringFilter_h +#define StringFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "ColumnFilter.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class RegExp; +class Row; +class StringColumn; + +class StringFilter : public ColumnFilter { +public: + StringFilter(Kind kind, const StringColumn &column, + RelationalOperator relOp, const std::string &value); + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + [[nodiscard]] std::optional stringValueRestrictionFor( + const std::string &column_name) const override; + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + +private: + const StringColumn &_column; + std::shared_ptr _regExp; +}; + +#endif // StringFilter_h diff --git a/src/StringPointerColumn.h b/src/StringPointerColumn.h new file mode 100644 index 0000000..f3c6d89 --- /dev/null +++ b/src/StringPointerColumn.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef StringPointerColumn_h +#define StringPointerColumn_h + +#include "config.h" // IWYU pragma: keep +#include "StringColumn.h" + +class StringPointerColumn : public StringColumn { +public: + StringPointerColumn(const std::string &name, const std::string &description, + const char *string) + : StringColumn(name, description, -1, -1, -1, 0), _string(string) {} + + [[nodiscard]] std::string getValue(Row /*unused*/) const override { + return _string; + } + +private: + const char *const _string; +}; + +#endif // StringPointerColumn_h diff --git a/src/StringUtils.cc b/src/StringUtils.cc new file mode 100644 index 0000000..61db431 --- /dev/null +++ b/src/StringUtils.cc @@ -0,0 +1,99 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "StringUtils.h" +#include +#include +#include +#include + +#ifdef CMC +#include +#include +#endif + +namespace mk { +std::string unsafe_tolower(const std::string &str) { + std::string result = str; + std::transform(str.begin(), str.end(), result.begin(), ::tolower); + return result; +} + +#ifdef CMC +std::string unsafe_toupper(const std::string &str) { + std::string result = str; + std::transform(str.begin(), str.end(), result.begin(), ::toupper); + return result; +} +#endif + +bool starts_with(const std::string &input, const std::string &test) { + return input.size() >= test.size() && + std::equal(test.begin(), test.end(), input.begin()); +} + +std::vector split(const std::string &str, char delimiter) { + std::istringstream iss(str); + std::vector result; + std::string field; + while (std::getline(iss, field, delimiter)) { + result.push_back(field); + } + return result; +} + +std::string lstrip(const std::string &str, const std::string &chars) { + auto pos = str.find_first_not_of(chars); + return pos == std::string::npos ? "" : str.substr(pos); +} + +std::string rstrip(const std::string &str, const std::string &chars) { + auto pos = str.find_last_not_of(chars); + return pos == std::string::npos ? "" : str.substr(0, pos + 1); +} + +std::string strip(const std::string &str, const std::string &chars) { + return rstrip(lstrip(str, chars), chars); +} + +std::pair nextField(const std::string &str, + const std::string &chars) { + auto s = lstrip(str, chars); + auto pos = s.find_first_of(chars); + return pos == std::string::npos + ? std::make_pair(s, "") + : std::make_pair(s.substr(0, pos), s.substr(pos + 1)); +} + +#ifdef CMC +std::string ipv4ToString(in_addr_t ipv4_address) { + char addr_buf[INET_ADDRSTRLEN]; + struct in_addr ia = {ipv4_address}; + inet_ntop(AF_INET, &ia, addr_buf, sizeof(addr_buf)); + return addr_buf; +} + +std::string portToString(in_port_t port) { return std::to_string(ntohs(port)); } +#endif +} // namespace mk diff --git a/src/StringUtils.h b/src/StringUtils.h new file mode 100644 index 0000000..2f86db4 --- /dev/null +++ b/src/StringUtils.h @@ -0,0 +1,84 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef StringUtils_h +#define StringUtils_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include + +#ifdef CMC +#include +#endif + +namespace mk { +std::string unsafe_tolower(const std::string &str); +#ifdef CMC +std::string unsafe_toupper(const std::string &str); +#endif + +bool starts_with(const std::string &input, const std::string &test); + +std::vector split(const std::string &str, char delimiter); + +std::string lstrip(const std::string &str, + const std::string &chars = " \t\n\v\f\r"); + +std::string rstrip(const std::string &str, + const std::string &chars = " \t\n\v\f\r"); + +std::string strip(const std::string &str, + const std::string &chars = " \t\n\v\f\r"); + +std::pair nextField( + const std::string &str, const std::string &chars = " \t\n\v\f\r"); + +#ifdef CMC +std::string ipv4ToString(in_addr_t ipv4_address); +std::string portToString(in_port_t port); +#endif +} // namespace mk + +template +struct FormattedBitSet { + const std::bitset &value; +}; + +template +std::ostream &operator<<(std::ostream &os, const FormattedBitSet &bs) { + size_t elems = 0; + for (size_t pos = 0; pos < N; ++pos) { + if (bs.value[pos]) { + os << (elems++ == 0 ? "{" : ", ") << pos; + } + } + return os << "}"; +} + +#endif // StringUtils_h diff --git a/src/Table.cc b/src/Table.cc new file mode 100644 index 0000000..3f5a946 --- /dev/null +++ b/src/Table.cc @@ -0,0 +1,101 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Table.h" +#include +#include "Column.h" +#include "DynamicColumn.h" +#include "MonitoringCore.h" +#include "StringUtils.h" +#include "nagios.h" + +Table::Table(MonitoringCore *mc) : _mc(mc) {} + +Table::~Table() = default; + +void Table::addColumn(std::unique_ptr col) { + _columns.emplace(col->name(), std::move(col)); +} + +void Table::addDynamicColumn(std::unique_ptr dyncol) { + _dynamic_columns.emplace(dyncol->name(), std::move(dyncol)); +} + +std::shared_ptr Table::column(std::string colname) const { + // Strip away a sequence of prefixes. + while (mk::starts_with(colname, namePrefix())) { + colname = colname.substr(namePrefix().size()); + } + + auto sep = colname.find(':'); + if (sep != std::string::npos) { + // TODO(sp) Use shared_ptr + return dynamicColumn(colname.substr(0, sep), colname.substr(sep + 1)); + } + + // First try exact match... + auto it = _columns.find(colname); + if (it != _columns.end()) { + return it->second; + } + + // ... then try to match with the prefix. + it = _columns.find(namePrefix() + colname); + if (it != _columns.end()) { + return it->second; + } + + throw std::runtime_error("table '" + name() + "' has no column '" + + colname + "'"); +} + +std::unique_ptr Table::dynamicColumn(const std::string &colname, + const std::string &rest) const { + auto it = _dynamic_columns.find(colname); + if (it == _dynamic_columns.end()) { + throw std::runtime_error("table '" + name() + + "' has no dynamic column '" + colname + "'"); + } + auto sep_pos = rest.find(':'); + if (sep_pos == std::string::npos) { + throw std::runtime_error("missing separator in dynamic column '" + + colname + "'"); + } + std::string colname2 = rest.substr(0, sep_pos); + if (colname2.empty()) { + throw std::runtime_error("empty column name for dynamic column '" + + colname + "'"); + } + return it->second->createColumn(colname2, rest.substr(sep_pos + 1)); +} + +bool Table::isAuthorized(Row /*unused*/, const contact * /*unused*/) const { + return true; +} + +Row Table::findObject(const std::string & /*unused*/) const { + return Row(nullptr); +} + +Logger *Table::logger() const { return _mc->loggerLivestatus(); } diff --git a/src/Table.h b/src/Table.h new file mode 100644 index 0000000..86692a9 --- /dev/null +++ b/src/Table.h @@ -0,0 +1,126 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Table_h +#define Table_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "Row.h" +#include "contact_fwd.h" +class Column; +class DynamicColumn; +class Logger; +class MonitoringCore; +class Query; + +// NOTE: This macro leads to undefined behaviour for non-POD/non-standard-layout +// classes, e.g. Entity, Host, etc., nevertheless we have to use it below. :-/ +#define DANGEROUS_OFFSETOF(typename, member) \ + (reinterpret_cast(&(reinterpret_cast(32))->member) - 32) + +/// A table-like view for some underlying data, exposed via LQL. +class Table { +public: + explicit Table(MonitoringCore *mc); + virtual ~Table(); + + void addColumn(std::unique_ptr col); + void addDynamicColumn(std::unique_ptr dyncol); + + template + [[nodiscard]] bool any_column(Predicate pred) const { + for (auto &c : _columns) { + if (pred(c.second)) { + return true; + } + } + return false; + } + + /// The name of the table, as used in the GET command. + [[nodiscard]] virtual std::string name() const = 0; + + /// \brief An optional prefix for column names. + /// + /// \todo Due to the way multisite works, column names are sometimes + /// prefixed by a variation of the table name (e.g. "hosts" => "host_"), but + /// the logic for this really shouldn't live on the cmc side. Furthermore, + /// multisite sometimes even seems to use a *sequence* of prefixes, which is + /// yet another a bug. Instead of fixing it there, it is currently papered + /// over on the cmc side. :-/ + [[nodiscard]] virtual std::string namePrefix() const = 0; + + /// \brief Retrieve a column with a give name. + /// + /// If the name contains a ':' then we have a dynamic column with column + /// arguments: The part before the colon is the column name of the dynamic + /// column and the part after it is the name of the fresh, dynamically + /// created column (up to the 2nd ':') and further arguments. This whole + /// mechanism is e.g. used to access RRD metrics data. + /// + /// \todo This member function is virtual just because TableStateHistory and + /// TableLog override it for some dubious reason: They first try the normal + /// lookup, and if that didn't find a column, the lookup is retried with a + /// "current_" prefix. This logic should probably not live in cmc at all. + [[nodiscard]] virtual std::shared_ptr column( + std::string colname) const; + + // NOTE: We can't make the query argument 'const' right now, because we call + // the non-const Query::processDataset() member function on it. This is a + // bit ugly, but only a minor issue: Each Query instance is only accessed in + // the thread which created it. Splitting up the Query class into a const + // and a non-const part can probably fix that wart. + // + // A much bigger problem is that we can't make answerQuery() itself 'const', + // because its impementations in TableStateHistory and TableCachedStatehist + // are non-const. Tables are shared between threads and the locking in the + // problematic answerQuery() implementations is a "bit" chaotic, so this can + // be a real correctness problem! This has to be fixed... + virtual void answerQuery(Query *query) = 0; + virtual bool isAuthorized(Row row, const contact *ctc) const; + [[nodiscard]] virtual Row findObject(const std::string &objectspec) const; + + template + [[nodiscard]] const T *rowData(Row row) const { + return row.rawData(); + } + + [[nodiscard]] MonitoringCore *core() const { return _mc; } + [[nodiscard]] Logger *logger() const; + +private: + MonitoringCore *_mc; + + [[nodiscard]] std::unique_ptr dynamicColumn( + const std::string &colname, const std::string &rest) const; + + std::map> _columns; + std::map> _dynamic_columns; +}; + +#endif // Table_h diff --git a/src/TableColumns.cc b/src/TableColumns.cc new file mode 100644 index 0000000..285aaea --- /dev/null +++ b/src/TableColumns.cc @@ -0,0 +1,88 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableColumns.h" +#include +#include +#include "Column.h" +#include "ColumnsColumn.h" +#include "Query.h" +#include "Row.h" + +TableColumns::TableColumns(MonitoringCore *mc) : Table(mc) { + addColumn(std::make_unique( + "table", "The name of the table", -1, -1, -1, 0, + ColumnsColumn::Type::table, *this)); + addColumn(std::make_unique( + "name", "The name of the column within the table", -1, -1, -1, 0, + ColumnsColumn::Type::name, *this)); + addColumn(std::make_unique( + "description", "A description of the column", -1, -1, -1, 0, + ColumnsColumn::Type::description, *this)); + addColumn(std::make_unique( + "type", "The data type of the column (int, float, string, list)", -1, + -1, -1, 0, ColumnsColumn::Type::type, *this)); +} + +std::string TableColumns::name() const { return "columns"; } + +std::string TableColumns::namePrefix() const { return "column_"; } + +void TableColumns::addTable(const Table &table) { _tables.push_back(&table); } + +void TableColumns::answerQuery(Query *query) { + for (auto table : _tables) { + (void)table->any_column([&](std::shared_ptr c) { + return !query->processDataset(Row(c.get())); + }); + } +} + +std::string TableColumns::getValue(const Column *column, + ColumnsColumn::Type colcol) const { + static const char *typenames[8] = {"int", "float", "string", "list", + "time", "dict", "blob", "null"}; + + switch (colcol) { + case ColumnsColumn::Type::table: + return tableNameOf(column); + case ColumnsColumn::Type::name: + return column->name(); + case ColumnsColumn::Type::description: + return column->description(); + case ColumnsColumn::Type::type: + return typenames[static_cast(column->type())]; + } + return ""; +} + +std::string TableColumns::tableNameOf(const Column *column) const { + for (auto table : _tables) { + if (table->any_column( + [&](std::shared_ptr c) { return c.get() == column; })) { + return table->name(); + } + } + return ""; // never reached if no bug +} diff --git a/src/TableColumns.h b/src/TableColumns.h new file mode 100644 index 0000000..af820ca --- /dev/null +++ b/src/TableColumns.h @@ -0,0 +1,54 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableColumns_h +#define TableColumns_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "ColumnsColumn.h" +#include "Table.h" +class Column; +class MonitoringCore; +class Query; + +class TableColumns : public Table { +public: + explicit TableColumns(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + + void addTable(const Table &table); + std::string getValue(const Column *column, + ColumnsColumn::Type colcol) const; + std::string tableNameOf(const Column *column) const; + +private: + std::vector _tables; +}; + +#endif // TableColumns_h diff --git a/src/TableCommands.cc b/src/TableCommands.cc new file mode 100644 index 0000000..9337a67 --- /dev/null +++ b/src/TableCommands.cc @@ -0,0 +1,59 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableCommands.h" +#include +#include +#include "Column.h" +#include "MonitoringCore.h" +#include "OffsetSStringColumn.h" +#include "Query.h" +#include "Row.h" + +TableCommands::TableCommands(MonitoringCore *mc) : Table(mc) { + addColumns(this, "", 0); +} + +std::string TableCommands::name() const { return "commands"; } + +std::string TableCommands::namePrefix() const { return "command_"; } + +// static +void TableCommands::addColumns(Table *table, const std::string &prefix, + int offset) { + table->addColumn(std::make_unique( + prefix + "name", "The name of the command", -1, -1, -1, + offset + DANGEROUS_OFFSETOF(Command, _name))); + table->addColumn(std::make_unique( + prefix + "line", "The shell command line", -1, -1, -1, + offset + DANGEROUS_OFFSETOF(Command, _command_line))); +} + +void TableCommands::answerQuery(Query *query) { + for (auto &cmd : core()->commands()) { + if (!query->processDataset(Row(&cmd))) { + break; + } + } +} diff --git a/src/TableCommands.h b/src/TableCommands.h new file mode 100644 index 0000000..ba018d4 --- /dev/null +++ b/src/TableCommands.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableCommands_h +#define TableCommands_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +class MonitoringCore; +class Query; + +class TableCommands : public Table { +public: + explicit TableCommands(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + + static void addColumns(Table *table, const std::string &prefix, int offset); +}; + +#endif // TableCommands_h diff --git a/src/TableComments.cc b/src/TableComments.cc new file mode 100644 index 0000000..9fc3a64 --- /dev/null +++ b/src/TableComments.cc @@ -0,0 +1,106 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableComments.h" +#include +#include +#include "Column.h" +#include "DowntimeOrComment.h" +#include "DowntimesOrComments.h" +#include "MonitoringCore.h" +#include "OffsetBoolColumn.h" +#include "OffsetIntColumn.h" +#include "OffsetSStringColumn.h" +#include "OffsetTimeColumn.h" +#include "Query.h" +#include "Row.h" +#include "Store.h" +#include "TableHosts.h" +#include "TableServices.h" +#include "auth.h" +#include "nagios.h" + +// TODO(sp): the dynamic data in this table must be locked with a mutex + +TableComments::TableComments(MonitoringCore *mc) : Table(mc) { + addColumn(std::make_unique( + "author", "The contact that entered the comment", -1, -1, -1, + DANGEROUS_OFFSETOF(Comment, _author_name))); + addColumn(std::make_unique( + "comment", "A comment text", -1, -1, -1, + DANGEROUS_OFFSETOF(Comment, _comment))); + addColumn(std::make_unique( + "id", "The id of the comment", -1, -1, -1, + DANGEROUS_OFFSETOF(Comment, _id))); + addColumn(std::make_unique( + "entry_time", "The time the entry was made as UNIX timestamp", -1, -1, + -1, DANGEROUS_OFFSETOF(Comment, _entry_time))); + addColumn(std::make_unique( + "type", "The type of the comment: 1 is host, 2 is service", -1, -1, -1, + DANGEROUS_OFFSETOF(Comment, _type))); + addColumn(std::make_unique( + "is_service", + "0, if this entry is for a host, 1 if it is for a service", -1, -1, -1, + DANGEROUS_OFFSETOF(Comment, _is_service))); + + addColumn(std::make_unique( + "persistent", "Whether this comment is persistent (0/1)", -1, -1, -1, + DANGEROUS_OFFSETOF(Comment, _persistent))); + addColumn(std::make_unique( + "source", "The source of the comment (0 is internal and 1 is external)", + -1, -1, -1, DANGEROUS_OFFSETOF(Comment, _source))); + addColumn(std::make_unique( + "entry_type", + "The type of the comment: 1 is user, 2 is downtime, 3 is flap and 4 is acknowledgement", + -1, -1, -1, DANGEROUS_OFFSETOF(Comment, _entry_type))); + addColumn(std::make_unique( + "expires", "Whether this comment expires", -1, -1, -1, + DANGEROUS_OFFSETOF(Comment, _expires))); + addColumn(std::make_unique( + "expire_time", "The time of expiry of this comment as a UNIX timestamp", + -1, -1, -1, DANGEROUS_OFFSETOF(Comment, _expire_time))); + + TableHosts::addColumns(this, "host_", DANGEROUS_OFFSETOF(Comment, _host), + -1); + TableServices::addColumns(this, "service_", + DANGEROUS_OFFSETOF(Comment, _service), + false /* no hosts table */); +} + +std::string TableComments::name() const { return "comments"; } + +std::string TableComments::namePrefix() const { return "comment_"; } + +void TableComments::answerQuery(Query *query) { + for (const auto &entry : core()->impl()->_comments) { + if (!query->processDataset(Row(entry.second.get()))) { + break; + } + } +} + +bool TableComments::isAuthorized(Row row, const contact *ctc) const { + auto dtc = rowData(row); + return is_authorized_for(core(), ctc, dtc->_host, dtc->_service); +} diff --git a/src/TableComments.h b/src/TableComments.h new file mode 100644 index 0000000..eb80a53 --- /dev/null +++ b/src/TableComments.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableComments_h +#define TableComments_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; +class Row; + +class TableComments : public Table { +public: + explicit TableComments(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; +}; + +#endif // TableComments_h diff --git a/src/TableContactGroups.cc b/src/TableContactGroups.cc new file mode 100644 index 0000000..dc66c80 --- /dev/null +++ b/src/TableContactGroups.cc @@ -0,0 +1,64 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableContactGroups.h" +#include +#include "Column.h" +#include "ContactGroupsMemberColumn.h" +#include "MonitoringCore.h" +#include "OffsetStringColumn.h" +#include "Query.h" +#include "nagios.h" + +extern contactgroup *contactgroup_list; + +TableContactGroups::TableContactGroups(MonitoringCore *mc) : Table(mc) { + addColumn(std::make_unique( + "name", "The name of the contactgroup", -1, -1, -1, + DANGEROUS_OFFSETOF(contactgroup, group_name))); + addColumn(std::make_unique( + "alias", "The alias of the contactgroup", -1, -1, -1, + DANGEROUS_OFFSETOF(contactgroup, alias))); + addColumn(std::make_unique( + "members", "A list of all members of this contactgroup", -1, -1, -1, + 0)); +} + +std::string TableContactGroups::name() const { return "contactgroups"; } + +std::string TableContactGroups::namePrefix() const { return "contactgroup_"; } + +void TableContactGroups::answerQuery(Query *query) { + for (contactgroup *cg = contactgroup_list; cg != nullptr; cg = cg->next) { + if (!query->processDataset(Row(cg))) { + break; + } + } +} + +Row TableContactGroups::findObject(const std::string &objectspec) const { + // TODO(sp): Remove ugly cast. + return Row(reinterpret_cast( + core()->find_contactgroup(objectspec))); +} diff --git a/src/TableContactGroups.h b/src/TableContactGroups.h new file mode 100644 index 0000000..aaf849e --- /dev/null +++ b/src/TableContactGroups.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableContactGroups_h +#define TableContactGroups_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Row.h" +#include "Table.h" +class MonitoringCore; +class Query; + +class TableContactGroups : public Table { +public: + explicit TableContactGroups(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + [[nodiscard]] Row findObject(const std::string &objectspec) const override; +}; + +#endif // TableContactGroups_h diff --git a/src/TableContacts.cc b/src/TableContacts.cc new file mode 100644 index 0000000..cc42c4f --- /dev/null +++ b/src/TableContacts.cc @@ -0,0 +1,142 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableContacts.h" +#include +#include "AttributeListAsIntColumn.h" +#include "AttributeListColumn.h" +#include "Column.h" +#include "CustomVarsDictColumn.h" +#include "CustomVarsNamesColumn.h" +#include "CustomVarsValuesColumn.h" +#include "OffsetIntColumn.h" +#include "OffsetStringColumn.h" +#include "Query.h" +#include "TimeperiodColumn.h" +#include "nagios.h" + +extern contact *contact_list; + +TableContacts::TableContacts(MonitoringCore *mc) : Table(mc) { + addColumns(this, "", -1); +} + +std::string TableContacts::name() const { return "contacts"; } + +std::string TableContacts::namePrefix() const { return "contact_"; } + +// static +void TableContacts::addColumns(Table *table, const std::string &prefix, + int indirect_offset) { + table->addColumn(std::make_unique( + prefix + "name", "The login name of the contact person", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(contact, name))); + table->addColumn(std::make_unique( + prefix + "alias", "The full name of the contact", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(contact, alias))); + table->addColumn(std::make_unique( + prefix + "email", "The email address of the contact", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(contact, email))); + table->addColumn(std::make_unique( + prefix + "pager", "The pager address of the contact", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(contact, pager))); + table->addColumn(std::make_unique( + prefix + "host_notification_period", + "The time period in which the contact will be notified about host problems", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, host_notification_period))); + table->addColumn(std::make_unique( + prefix + "service_notification_period", + "The time period in which the contact will be notified about service problems", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, service_notification_period))); + for (int i = 0; i < MAX_CONTACT_ADDRESSES; ++i) { + std::string b = "address" + std::to_string(i + 1); + table->addColumn(std::make_unique( + prefix + b, "The additional field " + b, indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, address[i]))); + } + + table->addColumn(std::make_unique( + prefix + "can_submit_commands", + "Wether the contact is allowed to submit commands (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, can_submit_commands))); + table->addColumn(std::make_unique( + prefix + "host_notifications_enabled", + "Wether the contact will be notified about host problems in general (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, host_notifications_enabled))); + table->addColumn(std::make_unique( + prefix + "service_notifications_enabled", + "Wether the contact will be notified about service problems in general (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, service_notifications_enabled))); + + table->addColumn(std::make_unique( + prefix + "in_host_notification_period", + "Wether the contact is currently in his/her host notification period (0/1)", + indirect_offset, + DANGEROUS_OFFSETOF(contact, host_notification_period_ptr), -1, 0)); + table->addColumn(std::make_unique( + prefix + "in_service_notification_period", + "Wether the contact is currently in his/her service notification period (0/1)", + indirect_offset, + DANGEROUS_OFFSETOF(contact, service_notification_period_ptr), -1, 0)); + + table->addColumn(std::make_unique( + prefix + "custom_variable_names", + "A list of all custom variables of the contact", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(contact, custom_variables))); + table->addColumn(std::make_unique( + prefix + "custom_variable_values", + "A list of the values of all custom variables of the contact", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, custom_variables))); + table->addColumn(std::make_unique( + prefix + "custom_variables", "A dictionary of the custom variables", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, custom_variables))); + table->addColumn(std::make_unique( + prefix + "modified_attributes", + "A bitmask specifying which attributes have been modified", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, modified_attributes))); + table->addColumn(std::make_unique( + prefix + "modified_attributes_list", + "A list of all modified attributes", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(contact, modified_attributes))); +} + +void TableContacts::answerQuery(Query *query) { + for (contact *ct = contact_list; ct != nullptr; ct = ct->next) { + if (!query->processDataset(Row(ct))) { + break; + } + } +} + +Row TableContacts::findObject(const std::string &objectspec) const { + return Row(find_contact(const_cast(objectspec.c_str()))); +} diff --git a/src/TableContacts.h b/src/TableContacts.h new file mode 100644 index 0000000..8805c7e --- /dev/null +++ b/src/TableContacts.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableContacts_h +#define TableContacts_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Row.h" +#include "Table.h" +class MonitoringCore; +class Query; + +class TableContacts : public Table { +public: + explicit TableContacts(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + [[nodiscard]] Row findObject(const std::string &objectspec) const override; + + static void addColumns(Table *table, const std::string &prefix, + int indirect_offset); +}; + +#endif // TableContacts_h diff --git a/src/TableDowntimes.cc b/src/TableDowntimes.cc new file mode 100644 index 0000000..9f86ed6 --- /dev/null +++ b/src/TableDowntimes.cc @@ -0,0 +1,107 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableDowntimes.h" +#include +#include +#include "Column.h" +#include "DowntimeOrComment.h" +#include "DowntimesOrComments.h" +#include "MonitoringCore.h" +#include "OffsetBoolColumn.h" +#include "OffsetIntColumn.h" +#include "OffsetSStringColumn.h" +#include "OffsetTimeColumn.h" +#include "Query.h" +#include "Row.h" +#include "Store.h" +#include "TableHosts.h" +#include "TableServices.h" +#include "auth.h" +#include "nagios.h" + +// TODO(sp): the dynamic data in this table must be locked with a mutex + +TableDowntimes::TableDowntimes(MonitoringCore *mc) : Table(mc) { + addColumn(std::make_unique( + "author", "The contact that scheduled the downtime", -1, -1, -1, + DANGEROUS_OFFSETOF(Downtime, _author_name))); + addColumn(std::make_unique( + "comment", "A comment text", -1, -1, -1, + DANGEROUS_OFFSETOF(Downtime, _comment))); + addColumn(std::make_unique( + "id", "The id of the downtime", -1, -1, -1, + DANGEROUS_OFFSETOF(Downtime, _id))); + addColumn(std::make_unique( + "entry_time", "The time the entry was made as UNIX timestamp", -1, -1, + -1, DANGEROUS_OFFSETOF(Downtime, _entry_time))); + addColumn(std::make_unique( + "type", + "The type of the downtime: 0 if it is active, 1 if it is pending", -1, + -1, -1, DANGEROUS_OFFSETOF(Downtime, _type))); + addColumn(std::make_unique( + "is_service", + "0, if this entry is for a host, 1 if it is for a service", -1, -1, -1, + DANGEROUS_OFFSETOF(Downtime, _is_service))); + + addColumn(std::make_unique( + "start_time", "The start time of the downtime as UNIX timestamp", -1, + -1, -1, DANGEROUS_OFFSETOF(Downtime, _start_time))); + addColumn(std::make_unique( + "end_time", "The end time of the downtime as UNIX timestamp", -1, -1, + -1, DANGEROUS_OFFSETOF(Downtime, _end_time))); + addColumn(std::make_unique( + "fixed", "A 1 if the downtime is fixed, a 0 if it is flexible", -1, -1, + -1, DANGEROUS_OFFSETOF(Downtime, _fixed))); + addColumn(std::make_unique( + "duration", "The duration of the downtime in seconds", -1, -1, -1, + DANGEROUS_OFFSETOF(Downtime, _duration))); + addColumn(std::make_unique( + "triggered_by", + "The id of the downtime this downtime was triggered by or 0 if it was not triggered by another downtime", + -1, -1, -1, DANGEROUS_OFFSETOF(Downtime, _triggered_by))); + + TableHosts::addColumns(this, "host_", DANGEROUS_OFFSETOF(Downtime, _host), + -1); + TableServices::addColumns(this, "service_", + DANGEROUS_OFFSETOF(Downtime, _service), + false /* no hosts table */); +} + +std::string TableDowntimes::name() const { return "downtimes"; } + +std::string TableDowntimes::namePrefix() const { return "downtime_"; } + +void TableDowntimes::answerQuery(Query *query) { + for (const auto &entry : core()->impl()->_downtimes) { + if (!query->processDataset(Row(entry.second.get()))) { + break; + } + } +} + +bool TableDowntimes::isAuthorized(Row row, const contact *ctc) const { + auto dtc = rowData(row); + return is_authorized_for(core(), ctc, dtc->_host, dtc->_service); +} diff --git a/src/TableDowntimes.h b/src/TableDowntimes.h new file mode 100644 index 0000000..3dac7b6 --- /dev/null +++ b/src/TableDowntimes.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableDowntimes_h +#define TableDowntimes_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; +class Row; + +class TableDowntimes : public Table { +public: + explicit TableDowntimes(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; +}; + +#endif // TableDowntimes_h diff --git a/src/TableEventConsole.cc b/src/TableEventConsole.cc new file mode 100644 index 0000000..ae158dd --- /dev/null +++ b/src/TableEventConsole.cc @@ -0,0 +1,227 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableEventConsole.h" +#include +#include +#include +#include +#include +#include +#include +#include "Column.h" +#include "EventConsoleConnection.h" +#include "Logger.h" +#include "Query.h" +#include "auth.h" + +namespace { +// NOTE: Keep this in sync with EC code. Ugly... +std::vector grepping_filters = { + "event_id", "event_text", "event_comment", "event_host", + "event_host_regex", "event_contact", "event_application", "event_rule_id", + "event_owner", "event_ipaddress", "event_core_host" + +}; + +class ECTableConnection : public EventConsoleConnection { +public: + ECTableConnection(MonitoringCore *mc, const Table &table, Query *query) + : EventConsoleConnection(mc->loggerLivestatus(), + mc->mkeventdSocketPath()) + , _mc(mc) + , _table(table) + , _query(query) {} + +private: + void sendRequest(std::ostream &os) override { + os << std::nounitbuf; + emitGET(os); + emitOutputFormat(os); + emitColumnsHeader(os); + emitTimeRangeFilter(os); + emitGreppingFilter(os); + os << std::endl; + } + + void emitGET(std::ostream &os) const { + // skip "eventconsole" prefix :-P + os << "GET " << _table.name().substr(12); + } + + void emitOutputFormat(std::ostream &os) const { + os << "\nOutputFormat: plain"; + } + + void emitColumnsHeader(std::ostream &os) { + os << "\nColumns:"; + // Initially we consider all columns used in the query... + auto all = _query->allColumns(); + // ... then we add some special columns which we might need irrespective + // of the actual query... + static std::unordered_set special_columns{ + // see receiveReply + "event_host", + // see isAuthorizedForEvent + "event_contact_groups_precedence", + // see isAuthorizedForEventViaContactGroups + "event_contact_groups"}; + (void)_table.any_column([&](const auto &col) { + if (special_columns.find(col->name()) != special_columns.end()) { + all.insert(col); + } + return false; + }); + // .. and then we ignore all host-related columns, they are implicitly + // joined later via ECRow._host later. + for (const auto &c : all) { + if (!mk::starts_with(c->name(), "host_")) { + os << " " << c->name(); + } + } + } + + void emitTimeRangeFilter(std::ostream &os) { + if (auto glb = _query->greatestLowerBoundFor("history_time")) { + os << "\nFilter: history_time >= " << *glb; + } + if (auto lub = _query->leastUpperBoundFor("history_time")) { + os << "\nFilter: history_time <= " << *lub; + } + } + + void emitGreppingFilter(std::ostream &os) { + for (const auto &column_name : grepping_filters) { + if (auto svr = _query->stringValueRestrictionFor(column_name)) { + os << "\nFilter: " << column_name << " = " << *svr; + } else { + auto glb = _query->greatestLowerBoundFor(column_name); + auto lub = _query->leastUpperBoundFor(column_name); + if (glb && lub && glb == lub) { + os << "\nFilter: " << column_name << " = " << *glb; + } + // NOTE: We could emit >= or <= constraints for cases where we + // know only one bound or the bounds are different, but the EC + // can't make use of that currently. + } + } + } + + void receiveReply(std::istream &is) override { + bool is_header = true; + std::vector headers; + do { + std::string line; + std::getline(is, line); + if (!is || line.empty()) { + return; + } + std::vector columns = mk::split(line, '\t'); + if (is_header) { + headers = std::move(columns); + is_header = false; + } else { + TableEventConsole::ECRow row; + int i = 0; + columns.resize(headers.size()); // just to be sure... + for (const auto &field : columns) { + row._map[headers[i++]] = field; + } + + auto it = row._map.find("event_host"); + row._host = it == row._map.end() + ? nullptr + : _mc->getHostByDesignation(it->second); + if (!_query->processDataset(Row(&row))) { + return; + } + } + } while (true); + } + + MonitoringCore *_mc; + const Table &_table; + Query *_query; +}; +} // namespace + +TableEventConsole::TableEventConsole(MonitoringCore *mc) : Table(mc) {} + +void TableEventConsole::answerQuery(Query *query) { + if (core()->mkeventdEnabled()) { + try { + ECTableConnection(core(), *this, query).run(); + } catch (const std::runtime_error &err) { + query->invalidRequest(err.what()); + } + } +} + +bool TableEventConsole::isAuthorizedForEvent(Row row, + const contact *ctc) const { + // TODO(sp) Remove evil casts below. + auto c = reinterpret_cast(ctc); + // NOTE: Further filtering in the GUI for mkeventd.seeunrelated permission + bool result = true; + auto precedence = std::static_pointer_cast( + column("event_contact_groups_precedence")) + ->getValue(row); + if (precedence == "rule") { + isAuthorizedForEventViaContactGroups(c, row, result) || + isAuthorizedForEventViaHost(c, row, result); + } else if (precedence == "host") { + isAuthorizedForEventViaHost(c, row, result) || + isAuthorizedForEventViaContactGroups(c, row, result); + } else { + Error(logger()) << "unknown precedence '" << precedence << "' in table " + << name(); + result = false; + } + return result; +} + +bool TableEventConsole::isAuthorizedForEventViaContactGroups( + const MonitoringCore::Contact *ctc, Row row, bool &result) const { + auto col = std::static_pointer_cast( + column("event_contact_groups")); + if (col->isNone(row)) { + return false; + } + for (const auto &name : + col->getValue(row, unknown_auth_user(), std::chrono::seconds(0))) { + if (core()->is_contact_member_of_contactgroup( + core()->find_contactgroup(name), ctc)) { + return (result = true, true); + } + } + return (result = false, true); +} + +bool TableEventConsole::isAuthorizedForEventViaHost( + const MonitoringCore::Contact *ctc, Row row, bool &result) const { + if (MonitoringCore::Host *hst = rowData(row)->_host) { + return (result = core()->host_has_contact(hst, ctc), true); + } + return false; +} diff --git a/src/TableEventConsole.h b/src/TableEventConsole.h new file mode 100644 index 0000000..3ea411b --- /dev/null +++ b/src/TableEventConsole.h @@ -0,0 +1,146 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableEventConsole_h +#define TableEventConsole_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include +#include "Column.h" +#include "DoubleColumn.h" +#include "IntColumn.h" +#include "ListColumn.h" +#include "MonitoringCore.h" +#include "Row.h" +#include "StringColumn.h" +#include "StringUtils.h" +#include "Table.h" +#include "TimeColumn.h" +#include "nagios.h" +class Query; + +class TableEventConsole : public Table { +public: + explicit TableEventConsole(MonitoringCore *mc); + + void answerQuery(Query *query) override; + + struct ECRow { + std::map _map; + MonitoringCore::Host *_host; + }; + +protected: + static std::string getRaw(Row row, const Column &column, + const std::string &default_value) { + if (auto r = column.columnData(row)) { + auto it = r->_map.find(column.name()); + if (it != r->_map.end()) { + return it->second; + } + } + return default_value; + } + + struct StringEventConsoleColumn : public StringColumn { + StringEventConsoleColumn(const std::string &name, + const std::string &description) + : StringColumn(name, description, -1, -1, -1, 0) {} + + [[nodiscard]] std::string getValue(Row row) const override { + return getRaw(row, *this, ""); + } + }; + + struct IntEventConsoleColumn : public IntColumn { + IntEventConsoleColumn(const std::string &name, + const std::string &description) + : IntColumn(name, description, -1, -1, -1, 0) {} + + int32_t getValue(Row row, + const contact * /* auth_user */) const override { + return static_cast(atol(getRaw(row, *this, "0").c_str())); + } + }; + + struct DoubleEventConsoleColumn : public DoubleColumn { + DoubleEventConsoleColumn(const std::string &name, + const std::string &description) + : DoubleColumn(name, description, -1, -1, -1, 0) {} + + [[nodiscard]] double getValue(Row row) const override { + return atof(getRaw(row, *this, "0").c_str()); + } + }; + + struct TimeEventConsoleColumn : public TimeColumn { + TimeEventConsoleColumn(const std::string &name, + const std::string &description) + : TimeColumn(name, description, -1, -1, -1, 0) {} + + private: + [[nodiscard]] std::chrono::system_clock::time_point getRawValue( + Row row) const override { + return std::chrono::system_clock::from_time_t( + static_cast( + atof(getRaw(row, *this, "0").c_str()))); + } + }; + + struct ListEventConsoleColumn : public ListColumn { + ListEventConsoleColumn(const std::string &name, + const std::string &description) + : ListColumn(name, description, -1, -1, -1, 0) {} + + std::vector getValue( + Row row, const contact * /*auth_user*/, + std::chrono::seconds /*timezone_offset*/) const override { + auto result = getRaw(row, *this, ""); + return result.empty() || result == "\002" + ? std::vector() + : mk::split(result.substr(1), '\001'); + } + + [[nodiscard]] bool isNone(Row row) const { + return getRaw(row, *this, "") == "\002"; + } + }; + + bool isAuthorizedForEvent(Row row, const contact *ctc) const; + +private: + bool isAuthorizedForEventViaContactGroups( + const MonitoringCore::Contact *ctc, Row row, bool &result) const; + bool isAuthorizedForEventViaHost(const MonitoringCore::Contact *ctc, + Row row, bool &result) const; +}; + +#endif // TableEventConsole_h diff --git a/src/TableEventConsoleEvents.cc b/src/TableEventConsoleEvents.cc new file mode 100644 index 0000000..824f868 --- /dev/null +++ b/src/TableEventConsoleEvents.cc @@ -0,0 +1,104 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableEventConsoleEvents.h" +#include +#include "Column.h" +#include "Row.h" +#include "Table.h" +#include "TableHosts.h" + +TableEventConsoleEvents::TableEventConsoleEvents(MonitoringCore *mc) + : TableEventConsole(mc) { + addColumns(this); +} + +// static +void TableEventConsoleEvents::addColumns(Table *table) { + table->addColumn(std::make_unique( + "event_id", "The unique ID for this event")); + table->addColumn(std::make_unique( + "event_count", + "The number of occurrences of this event within period")); + table->addColumn(std::make_unique( + "event_text", "The textual description of the event")); + table->addColumn(std::make_unique( + "event_first", + "Time of the first occurrence of the event (Unix timestamp)")); + table->addColumn(std::make_unique( + "event_last", + "Time of the last occurrence of this event (Unix timestamp)")); + table->addColumn(std::make_unique( + "event_comment", "Event comment")); + table->addColumn(std::make_unique( + "event_sl", "The service level for this event")); + table->addColumn(std::make_unique( + "event_host", "Host name for this event")); + table->addColumn(std::make_unique( + "event_contact", "Contact information")); + table->addColumn(std::make_unique( + "event_application", "Syslog tag/application")); + table->addColumn(std::make_unique( + "event_pid", "The process ID of the originating process")); + table->addColumn(std::make_unique( + "event_priority", "Syslog priority")); + table->addColumn(std::make_unique( + "event_facility", "Syslog facility")); + table->addColumn(std::make_unique( + "event_rule_id", "The ID of the rule")); + table->addColumn(std::make_unique( + "event_state", "The state of the event (0/1/2/3)")); + table->addColumn(std::make_unique( + "event_phase", + "The phase the event is currently in (one of open/closed/delayed/counting/ack)")); + table->addColumn(std::make_unique( + "event_owner", "The owner of the event")); + table->addColumn(std::make_unique( + "event_match_groups", "Text groups from regular expression match")); + table->addColumn(std::make_unique( + "event_contact_groups", "Contact groups")); + table->addColumn(std::make_unique( + "event_contact_groups_precedence", + "Whether or not the host- or rule groups have precedence")); + table->addColumn(std::make_unique( + "event_ipaddress", "The IP address where the event originated")); + table->addColumn(std::make_unique( + "event_host_in_downtime", + "Whether or not the host (if found in core) was in downtime during event creation (0/1)")); + + TableHosts::addColumns(table, "host_", DANGEROUS_OFFSETOF(ECRow, _host), + -1); +} + +std::string TableEventConsoleEvents::name() const { + return "eventconsoleevents"; +} + +std::string TableEventConsoleEvents::namePrefix() const { + return "eventconsoleevents_"; +} + +bool TableEventConsoleEvents::isAuthorized(Row row, const contact *ctc) const { + return isAuthorizedForEvent(row, ctc); +} diff --git a/src/TableEventConsoleEvents.h b/src/TableEventConsoleEvents.h new file mode 100644 index 0000000..ebcccad --- /dev/null +++ b/src/TableEventConsoleEvents.h @@ -0,0 +1,45 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableEventConsoleEvents_h +#define TableEventConsoleEvents_h + +#include "config.h" // IWYU pragma: keep +#include +#include "TableEventConsole.h" +#include "nagios.h" +class MonitoringCore; +class Row; +class Table; + +class TableEventConsoleEvents : public TableEventConsole { +public: + explicit TableEventConsoleEvents(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + static void addColumns(Table *table); + bool isAuthorized(Row row, const contact *ctc) const override; +}; + +#endif // TableEventConsoleEvents_h diff --git a/src/TableEventConsoleHistory.cc b/src/TableEventConsoleHistory.cc new file mode 100644 index 0000000..17f05ab --- /dev/null +++ b/src/TableEventConsoleHistory.cc @@ -0,0 +1,59 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableEventConsoleHistory.h" +#include +#include "Column.h" +#include "Row.h" +#include "TableEventConsoleEvents.h" + +TableEventConsoleHistory::TableEventConsoleHistory(MonitoringCore *mc) + : TableEventConsole(mc) { + addColumn(std::make_unique( + "history_line", "The line number of the event in the history file")); + addColumn(std::make_unique( + "history_time", + "Time when the event was written into the history file (Unix timestamp)")); + addColumn(std::make_unique( + "history_what", + "What happened (one of ARCHIVED/AUTODELETE/CANCELLED/CHANGESTATE/COUNTFAILED/COUNTREACHED/DELAYOVER/DELETE/EMAIL/EXPIRED/NEW/NOCOUNT/ORPHANED/SCRIPT/UPDATE)")); + addColumn(std::make_unique( + "history_who", "The user who triggered the command")); + addColumn(std::make_unique( + "history_addinfo", + "Additional information, like email recipient/subject or action ID")); + TableEventConsoleEvents::addColumns(this); +} + +std::string TableEventConsoleHistory::name() const { + return "eventconsolehistory"; +} + +std::string TableEventConsoleHistory::namePrefix() const { + return "eventconsolehistory_"; +} + +bool TableEventConsoleHistory::isAuthorized(Row row, const contact *ctc) const { + return isAuthorizedForEvent(row, ctc); +} diff --git a/src/TableEventConsoleHistory.h b/src/TableEventConsoleHistory.h new file mode 100644 index 0000000..9759e6e --- /dev/null +++ b/src/TableEventConsoleHistory.h @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableEventConsoleHistory_h +#define TableEventConsoleHistory_h + +#include "config.h" // IWYU pragma: keep +#include +#include "TableEventConsole.h" +#include "nagios.h" +class MonitoringCore; +class Row; + +class TableEventConsoleHistory : public TableEventConsole { +public: + explicit TableEventConsoleHistory(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + bool isAuthorized(Row row, const contact *ctc) const override; +}; + +#endif // TableEventConsoleHistory_h diff --git a/src/TableEventConsoleReplication.cc b/src/TableEventConsoleReplication.cc new file mode 100644 index 0000000..ebafced --- /dev/null +++ b/src/TableEventConsoleReplication.cc @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableEventConsoleReplication.h" +#include +#include "DynamicColumn.h" +#include "DynamicEventConsoleReplicationColumn.h" +#include "Query.h" +#include "Row.h" + +TableEventConsoleReplication::TableEventConsoleReplication(MonitoringCore *mc) + : Table(mc) { + addDynamicColumn(std::make_unique( + "value", "The replication value", mc, -1, -1, -1)); +} + +std::string TableEventConsoleReplication::name() const { + return "eventconsolereplication"; +} + +std::string TableEventConsoleReplication::namePrefix() const { + return "eventconsolereplication_"; +} + +void TableEventConsoleReplication::answerQuery(Query *query) { + query->processDataset(Row(nullptr)); +} diff --git a/src/TableEventConsoleReplication.h b/src/TableEventConsoleReplication.h new file mode 100644 index 0000000..3556e56 --- /dev/null +++ b/src/TableEventConsoleReplication.h @@ -0,0 +1,42 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableEventConsoleReplication_h +#define TableEventConsoleReplication_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +class MonitoringCore; +class Query; + +class TableEventConsoleReplication : public Table { +public: + explicit TableEventConsoleReplication(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; +}; + +#endif // TableEventConsoleReplication_h diff --git a/src/TableEventConsoleRules.cc b/src/TableEventConsoleRules.cc new file mode 100644 index 0000000..769b84c --- /dev/null +++ b/src/TableEventConsoleRules.cc @@ -0,0 +1,42 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableEventConsoleRules.h" +#include +#include "Column.h" + +TableEventConsoleRules::TableEventConsoleRules(MonitoringCore *mc) + : TableEventConsole(mc) { + addColumn(std::make_unique("rule_id", + "The ID of the rule")); + + addColumn(std::make_unique( + "rule_hits", "The times rule matched an incoming message")); +} + +std::string TableEventConsoleRules::name() const { return "eventconsolerules"; } + +std::string TableEventConsoleRules::namePrefix() const { + return "eventconsolerules_"; +} diff --git a/src/TableEventConsoleRules.h b/src/TableEventConsoleRules.h new file mode 100644 index 0000000..ddd5b3e --- /dev/null +++ b/src/TableEventConsoleRules.h @@ -0,0 +1,40 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableEventConsoleRules_h +#define TableEventConsoleRules_h + +#include "config.h" // IWYU pragma: keep +#include +#include "TableEventConsole.h" +class MonitoringCore; + +class TableEventConsoleRules : public TableEventConsole { +public: + explicit TableEventConsoleRules(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; +}; + +#endif // TableEventConsoleRules_h diff --git a/src/TableEventConsoleStatus.cc b/src/TableEventConsoleStatus.cc new file mode 100644 index 0000000..adaa359 --- /dev/null +++ b/src/TableEventConsoleStatus.cc @@ -0,0 +1,134 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableEventConsoleStatus.h" +#include +#include "Column.h" + +TableEventConsoleStatus::TableEventConsoleStatus(MonitoringCore *mc) + : TableEventConsole(mc) { + addColumn(std::make_unique( + "status_config_load_time", + "The time when the Event Console config was loaded")); + addColumn(std::make_unique( + "status_num_open_events", "The number of currently open events")); + addColumn(std::make_unique( + "status_virtual_memory_size", + "The current virtual memory size in bytes")); + + addColumn(std::make_unique( + "status_messages", + "The number of messages received since startup of the Event Console")); + addColumn(std::make_unique( + "status_message_rate", "The incoming message rate")); + addColumn(std::make_unique( + "status_average_message_rate", "The average incoming message rate")); + addColumn(std::make_unique( + "status_connects", "The number of connects")); + addColumn(std::make_unique("status_connect_rate", + "The connect rate")); + addColumn(std::make_unique( + "status_average_connect_rate", "The average connect rate")); + addColumn(std::make_unique( + "status_rule_tries", "The number of rule tries")); + addColumn(std::make_unique( + "status_rule_trie_rate", "The rule trie rate")); + addColumn(std::make_unique( + "status_average_rule_trie_rate", "The average rule trie rate")); + addColumn(std::make_unique( + "status_drops", + "The number of message drops (decided by a rule) since startup of the Event Console")); + addColumn(std::make_unique("status_drop_rate", + "The drop rate")); + addColumn(std::make_unique( + "status_average_drop_rate", "The average drop rate")); + addColumn(std::make_unique( + "status_overflows", + "The number of message overflows, i.e. messages simply dropped due to an overflow of the Event Console")); + addColumn(std::make_unique("status_overflow_rate", + "The overflow rate")); + addColumn(std::make_unique( + "status_average_overflow_rate", "The average overflow rate")); + addColumn(std::make_unique( + "status_events", + "The number of events received since startup of the Event Console")); + addColumn(std::make_unique("status_event_rate", + "The event rate")); + addColumn(std::make_unique( + "status_average_event_rate", "The average event rate")); + + addColumn(std::make_unique( + "status_rule_hits", + "The number of rule hits since startup of the Event Console")); + addColumn(std::make_unique("status_rule_hit_rate", + "The rule hit rate")); + addColumn(std::make_unique( + "status_average_rule_hit_rate", "The average rule hit rate")); + + addColumn(std::make_unique( + "status_average_processing_time", + "The average incoming message processing time")); + addColumn(std::make_unique( + "status_average_request_time", + "The average status client request time")); + addColumn(std::make_unique( + "status_average_sync_time", "The average sync time")); + addColumn(std::make_unique( + "status_replication_slavemode", + "The replication slavemode (empty or one of sync/takeover)")); + addColumn(std::make_unique( + "status_replication_last_sync", + "Time of the last replication (Unix timestamp)")); + addColumn(std::make_unique( + "status_replication_success", + "Whether the replication succeeded (0/1)")); + + addColumn(std::make_unique( + "status_event_limit_host", + "The currently active event limit for hosts")); + addColumn(std::make_unique( + "status_event_limit_rule", + "The currently active event limit for rules")); + addColumn(std::make_unique( + "status_event_limit_overall", + "The currently active event limit for all events")); + + addColumn(std::make_unique( + "status_event_limit_active_hosts", + "List of host names with active event limit")); + addColumn(std::make_unique( + "status_event_limit_active_rules", + "List of rule IDs which rules event limit is active")); + addColumn(std::make_unique( + "status_event_limit_active_overall", + "Whether or not the overall event limit is in effect (0/1)")); +} + +std::string TableEventConsoleStatus::name() const { + return "eventconsolestatus"; +} + +std::string TableEventConsoleStatus::namePrefix() const { + return "eventconsolestatus_"; +} diff --git a/src/TableEventConsoleStatus.h b/src/TableEventConsoleStatus.h new file mode 100644 index 0000000..ddbc253 --- /dev/null +++ b/src/TableEventConsoleStatus.h @@ -0,0 +1,40 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableEventConsoleStatus_h +#define TableEventConsoleStatus_h + +#include "config.h" // IWYU pragma: keep +#include +#include "TableEventConsole.h" +class MonitoringCore; + +class TableEventConsoleStatus : public TableEventConsole { +public: + explicit TableEventConsoleStatus(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; +}; + +#endif // TableEventConsoleStatus_h diff --git a/src/TableHostGroups.cc b/src/TableHostGroups.cc new file mode 100644 index 0000000..f668aea --- /dev/null +++ b/src/TableHostGroups.cc @@ -0,0 +1,188 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableHostGroups.h" +#include +#include "Column.h" +#include "HostListColumn.h" +#include "HostListStateColumn.h" +#include "OffsetStringColumn.h" +#include "Query.h" +#include "auth.h" +#include "nagios.h" + +/* this might be a hack (accessing Nagios' internal structures. + Hi Ethan: please help me here: how should this be code to be + portable? */ +extern hostgroup *hostgroup_list; + +TableHostGroups::TableHostGroups(MonitoringCore *mc) : Table(mc) { + addColumns(this, "", -1); +} + +std::string TableHostGroups::name() const { return "hostgroups"; } + +std::string TableHostGroups::namePrefix() const { return "hostgroup_"; } + +// static +void TableHostGroups::addColumns(Table *table, const std::string &prefix, + int indirect_offset) { + table->addColumn(std::make_unique( + prefix + "name", "Name of the hostgroup", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(hostgroup, group_name))); + table->addColumn(std::make_unique( + prefix + "alias", "An alias of the hostgroup", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(hostgroup, alias))); + table->addColumn(std::make_unique( + prefix + "notes", "Optional notes to the hostgroup", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(hostgroup, notes))); + table->addColumn(std::make_unique( + prefix + "notes_url", + "An optional URL with further information about the hostgroup", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, notes_url))); + table->addColumn(std::make_unique( + prefix + "action_url", + "An optional URL to custom actions or information about the hostgroup", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, action_url))); + table->addColumn(std::make_unique( + prefix + "members", + "A list of all host names that are members of the hostgroup", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), false)); + table->addColumn(std::make_unique( + prefix + "members_with_state", + "A list of all host names that are members of the hostgroup together with state and has_been_checked", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), true)); + + table->addColumn(std::make_unique( + prefix + "worst_host_state", + "The worst state of all of the groups' hosts (UP <= UNREACHABLE <= DOWN)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::worst_hst_state)); + table->addColumn(std::make_unique( + prefix + "num_hosts", "The total number of hosts in the group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_hst)); + table->addColumn(std::make_unique( + prefix + "num_hosts_pending", + "The number of hosts in the group that are pending", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), table->core(), + HostListStateColumn::Type::num_hst_pending)); + table->addColumn(std::make_unique( + prefix + "num_hosts_up", "The number of hosts in the group that are up", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_hst_up)); + table->addColumn(std::make_unique( + prefix + "num_hosts_down", + "The number of hosts in the group that are down", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(hostgroup, members), table->core(), + HostListStateColumn::Type::num_hst_down)); + table->addColumn(std::make_unique( + prefix + "num_hosts_unreach", + "The number of hosts in the group that are unreachable", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_hst_unreach)); + + table->addColumn(std::make_unique( + prefix + "num_services", + "The total number of services of hosts in this group", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), table->core(), + HostListStateColumn::Type::num_svc)); + + // soft states + table->addColumn(std::make_unique( + prefix + "worst_service_state", + "The worst state of all services that belong to a host of this group (OK <= WARN <= UNKNOWN <= CRIT)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::worst_svc_state)); + table->addColumn(std::make_unique( + prefix + "num_services_pending", + "The total number of services with the state Pending of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_pending)); + table->addColumn(std::make_unique( + prefix + "num_services_ok", + "The total number of services with the state OK of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_ok)); + table->addColumn(std::make_unique( + prefix + "num_services_warn", + "The total number of services with the state WARN of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_warn)); + table->addColumn(std::make_unique( + prefix + "num_services_crit", + "The total number of services with the state CRIT of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_crit)); + table->addColumn(std::make_unique( + prefix + "num_services_unknown", + "The total number of services with the state UNKNOWN of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_unknown)); + + // hard state + table->addColumn(std::make_unique( + prefix + "worst_service_hard_state", + "The worst state of all services that belong to a host of this group (OK <= WARN <= UNKNOWN <= CRIT)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::worst_svc_hard_state)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_ok", + "The total number of services with the state OK of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_hard_ok)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_warn", + "The total number of services with the state WARN of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_hard_warn)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_crit", + "The total number of services with the state CRIT of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_hard_crit)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_unknown", + "The total number of services with the state UNKNOWN of hosts in this group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(hostgroup, members), + table->core(), HostListStateColumn::Type::num_svc_hard_unknown)); +} + +void TableHostGroups::answerQuery(Query *query) { + for (hostgroup *hg = hostgroup_list; hg != nullptr; hg = hg->next) { + if (!query->processDataset(Row(hg))) { + break; + } + } +} + +Row TableHostGroups::findObject(const std::string &objectspec) const { + return Row(find_hostgroup(const_cast(objectspec.c_str()))); +} + +bool TableHostGroups::isAuthorized(Row row, const contact *ctc) const { + return is_authorized_for_host_group(core(), rowData(row), ctc); +} diff --git a/src/TableHostGroups.h b/src/TableHostGroups.h new file mode 100644 index 0000000..2a7605b --- /dev/null +++ b/src/TableHostGroups.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableHostGroups_h +#define TableHostGroups_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Row.h" +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; + +class TableHostGroups : public Table { +public: + explicit TableHostGroups(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + [[nodiscard]] Row findObject(const std::string &objectspec) const override; + bool isAuthorized(Row row, const contact *ctc) const override; + + static void addColumns(Table *table, const std::string &prefix, + int indirect_offset); +}; + +#endif // TableHostGroups_h diff --git a/src/TableHosts.cc b/src/TableHosts.cc new file mode 100644 index 0000000..af2b057 --- /dev/null +++ b/src/TableHosts.cc @@ -0,0 +1,680 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableHosts.h" +#include +#include +#include +#include "AttributeListAsIntColumn.h" +#include "AttributeListColumn.h" +#include "Column.h" +#include "CommentColumn.h" +#include "ContactGroupsColumn.h" +#include "CustomTimeperiodColumn.h" +#include "CustomVarsDictColumn.h" +#include "CustomVarsExplicitColumn.h" +#include "CustomVarsNamesColumn.h" +#include "CustomVarsValuesColumn.h" +#include "DowntimeColumn.h" +#include "DynamicColumn.h" +#include "DynamicLogwatchFileColumn.h" +#include "HostContactsColumn.h" +#include "HostFileColumn.h" +#include "HostGroupsColumn.h" +#include "HostListColumn.h" +#include "HostSpecialDoubleColumn.h" +#include "HostSpecialIntColumn.h" +#include "Logger.h" +#include "LogwatchListColumn.h" +#include "MetricsColumn.h" +#include "MonitoringCore.h" +#include "OffsetDoubleColumn.h" +#include "OffsetIntColumn.h" +#include "OffsetPerfdataColumn.h" +#include "OffsetStringColumn.h" +#include "OffsetStringHostMacroColumn.h" +#include "OffsetTimeColumn.h" +#include "Query.h" +#include "ServiceListColumn.h" +#include "ServiceListStateColumn.h" +#include "TimeperiodColumn.h" +#include "auth.h" +#include "nagios.h" + +extern host *host_list; + +TableHosts::TableHosts(MonitoringCore *mc) : Table(mc) { + addColumns(this, "", -1, -1); +} + +std::string TableHosts::name() const { return "hosts"; } + +std::string TableHosts::namePrefix() const { return "host_"; } + +// static +void TableHosts::addColumns(Table *table, const std::string &prefix, + int indirect_offset, int extra_offset) { + table->addColumn(std::make_unique( + prefix + "name", "Host name", indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, name))); + table->addColumn(std::make_unique( + prefix + "display_name", + "Optional display name of the host - not used by Nagios' web interface", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, display_name))); + table->addColumn(std::make_unique( + prefix + "alias", "An alias name for the host", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, alias))); + table->addColumn(std::make_unique( + prefix + "address", "IP address", indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, address))); +#ifdef NAGIOS4 + table->addColumn(std::make_unique( + prefix + "check_command", + "Nagios command for active host check of this host", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, check_command))); + table->addColumn(std::make_unique( + prefix + "check_command_expanded", + "Nagios command for active host check of this host with the macros expanded", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, check_command))); +#else + table->addColumn(std::make_unique( + prefix + "check_command", + "Nagios command for active host check of this host", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, host_check_command))); + table->addColumn(std::make_unique( + prefix + "check_command_expanded", + "Nagios command for active host check of this host with the macros expanded", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, host_check_command))); +#endif + table->addColumn(std::make_unique( + prefix + "event_handler", "Nagios command used as event handler", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, event_handler))); + table->addColumn(std::make_unique( + prefix + "notification_period", + "Time period in which problems of this host will be notified. If empty then notification will be always", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, notification_period))); + table->addColumn(std::make_unique( + prefix + "check_period", + "Time period in which this host will be checked. If empty then the host will always be checked.", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, check_period))); + table->addColumn(std::make_unique( + prefix + "service_period", "The name of the service period of the host", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, custom_variables), "SERVICE_PERIOD")); + table->addColumn(std::make_unique( + prefix + "notes", "Optional notes for this host", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, notes))); + table->addColumn(std::make_unique( + prefix + "notes_expanded", + "The same as notes, but with the most important macros expanded", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, notes))); + table->addColumn(std::make_unique( + prefix + "notes_url", + "An optional URL with further information about the host", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, notes_url))); + table->addColumn(std::make_unique( + prefix + "notes_url_expanded", + "Same es notes_url, but with the most important macros expanded", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, notes_url))); + table->addColumn(std::make_unique( + prefix + "action_url", + "An optional URL to custom actions or information about this host", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, action_url))); + table->addColumn(std::make_unique( + prefix + "action_url_expanded", + "The same as action_url, but with the most important macros expanded", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, action_url))); + table->addColumn(std::make_unique( + prefix + "plugin_output", "Output of the last host check", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, plugin_output))); + table->addColumn(std::make_unique( + prefix + "perf_data", + "Optional performance data of the last host check", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, perf_data))); + table->addColumn(std::make_unique( + prefix + "icon_image", + "The name of an image file to be used in the web pages", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, icon_image))); + table->addColumn(std::make_unique( + prefix + "icon_image_expanded", + "The same as icon_image, but with the most important macros expanded", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, icon_image))); + table->addColumn(std::make_unique( + prefix + "icon_image_alt", "Alternative text for the icon_image", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, icon_image_alt))); + table->addColumn(std::make_unique( + prefix + "statusmap_image", + "The name of in image file for the status map", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, statusmap_image))); + table->addColumn(std::make_unique( + prefix + "long_plugin_output", "Complete output from check plugin", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, long_plugin_output))); + + table->addColumn(std::make_unique( + prefix + "initial_state", "Initial host state", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, initial_state))); + table->addColumn(std::make_unique( + prefix + "max_check_attempts", + "Max check attempts for active host checks", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, max_attempts))); + table->addColumn(std::make_unique( + prefix + "flap_detection_enabled", + "Whether flap detection is enabled (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, flap_detection_enabled))); + table->addColumn(std::make_unique( + prefix + "check_freshness", + "Whether freshness checks are activated (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, check_freshness))); + table->addColumn(std::make_unique( + prefix + "process_performance_data", + "Whether processing of performance data is enabled (0/1)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, process_performance_data))); +#ifndef NAGIOS4 + table->addColumn(std::make_unique( + prefix + "accept_passive_checks", + "Whether passive host checks are accepted (0/1)", indirect_offset, + extra_offset, -1, + DANGEROUS_OFFSETOF(host, accept_passive_host_checks))); +#else + table->addColumn(std::make_unique( + prefix + "accept_passive_checks", + "Whether passive host checks are accepted (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, accept_passive_checks))); +#endif // NAGIOS4 + table->addColumn(std::make_unique( + prefix + "event_handler_enabled", + "Whether event handling is enabled (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, event_handler_enabled))); + table->addColumn(std::make_unique( + prefix + "acknowledgement_type", + "Type of acknowledgement (0: none, 1: normal, 2: stick)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, acknowledgement_type))); + table->addColumn(std::make_unique( + prefix + "check_type", "Type of check (0: active, 1: passive)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, check_type))); + table->addColumn(std::make_unique( + prefix + "last_state", "State before last state change", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, last_state))); + table->addColumn(std::make_unique( + prefix + "last_hard_state", "Last hard state", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, last_hard_state))); + table->addColumn(std::make_unique( + prefix + "current_attempt", "Number of the current check attempts", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, current_attempt))); +#ifndef NAGIOS4 + table->addColumn(std::make_unique( + prefix + "last_notification", + "Time of the last notification (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, last_host_notification))); + table->addColumn(std::make_unique( + prefix + "next_notification", + "Time of the next notification (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, next_host_notification))); +#else + table->addColumn(std::make_unique( + prefix + "last_notification", + "Time of the last notification (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, last_notification))); + table->addColumn(std::make_unique( + prefix + "next_notification", + "Time of the next notification (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, next_notification))); +#endif // NAGIOS4 + table->addColumn(std::make_unique( + prefix + "next_check", + "Scheduled time for the next check (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, next_check))); + table->addColumn(std::make_unique( + prefix + "last_hard_state_change", + "Time of the last hard state change (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, last_hard_state_change))); + table->addColumn(std::make_unique( + prefix + "has_been_checked", + "Whether the host has already been checked (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, has_been_checked))); + table->addColumn(std::make_unique( + prefix + "current_notification_number", + "Number of the current notification", indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, current_notification_number))); + table->addColumn(std::make_unique( + prefix + "pending_flex_downtime", + "Number of pending flexible downtimes", indirect_offset, extra_offset, + -1, DANGEROUS_OFFSETOF(host, pending_flex_downtime))); + table->addColumn(std::make_unique( + prefix + "total_services", "The total number of services of the host", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, total_services))); + // Note: this is redundant with "active_checks_enabled". Nobody noted this + // before... + table->addColumn(std::make_unique( + prefix + "checks_enabled", + "Whether checks of the host are enabled (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, checks_enabled))); + table->addColumn(std::make_unique( + prefix + "notifications_enabled", + "Whether notifications of the host are enabled (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, notifications_enabled))); + table->addColumn(std::make_unique( + prefix + "acknowledged", + "Whether the current host problem has been acknowledged (0/1)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, problem_has_been_acknowledged))); + table->addColumn(std::make_unique( + prefix + "state", + "The current state of the host (0: up, 1: down, 2: unreachable)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, current_state))); + table->addColumn(std::make_unique( + prefix + "state_type", "Type of the current state (0: soft, 1: hard)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, state_type))); + table->addColumn(std::make_unique( + prefix + "no_more_notifications", + "Whether to stop sending notifications (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, no_more_notifications))); + table->addColumn(std::make_unique( + prefix + "check_flapping_recovery_notification", + "Whether to check to send a recovery notification when flapping stops (0/1)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, check_flapping_recovery_notification))); + table->addColumn(std::make_unique( + prefix + "last_check", "Time of the last check (Unix timestamp)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, last_check))); + table->addColumn(std::make_unique( + prefix + "last_state_change", + "Time of the last state change - soft or hard (Unix timestamp)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, last_state_change))); + + table->addColumn(std::make_unique( + prefix + "last_time_up", + "The last time the host was UP (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, last_time_up))); + table->addColumn(std::make_unique( + prefix + "last_time_down", + "The last time the host was DOWN (Unix timestamp)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, last_time_down))); + table->addColumn(std::make_unique( + prefix + "last_time_unreachable", + "The last time the host was UNREACHABLE (Unix timestamp)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, last_time_unreachable))); + + table->addColumn(std::make_unique( + prefix + "is_flapping", "Whether the host state is flapping (0/1)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, is_flapping))); + table->addColumn(std::make_unique( + prefix + "scheduled_downtime_depth", + "The number of downtimes this host is currently in", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, scheduled_downtime_depth))); + table->addColumn(std::make_unique( + prefix + "is_executing", + "is there a host check currently running... (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, is_executing))); + table->addColumn(std::make_unique( + prefix + "active_checks_enabled", + "Whether active checks are enabled for the host (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, checks_enabled))); + table->addColumn(std::make_unique( + prefix + "check_options", + "The current check option, forced, normal, freshness... (0-2)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, check_options))); +#ifndef NAGIOS4 + table->addColumn(std::make_unique( + prefix + "obsess_over_host", + "The current obsess_over_host setting... (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, obsess_over_host))); +#else + table->addColumn(std::make_unique( + prefix + "obsess_over_host", + "The current obsess_over_host setting... (0/1)", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, obsess))); +#endif // NAGIOS4 + table->addColumn(std::make_unique( + prefix + "modified_attributes", + "A bitmask specifying which attributes have been modified", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, modified_attributes))); + table->addColumn(std::make_unique( + prefix + "modified_attributes_list", + "A list of all modified attributes", indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, modified_attributes))); + + // columns of type double + table->addColumn(std::make_unique( + prefix + "check_interval", + "Number of basic interval lengths between two scheduled checks of the host", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, check_interval))); + table->addColumn(std::make_unique( + prefix + "retry_interval", + "Number of basic interval lengths between checks when retrying after a soft error", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, retry_interval))); + table->addColumn(std::make_unique( + prefix + "notification_interval", + "Interval of periodic notification or 0 if its off", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, notification_interval))); + table->addColumn(std::make_unique( + prefix + "first_notification_delay", + "Delay before the first notification", indirect_offset, extra_offset, + -1, DANGEROUS_OFFSETOF(host, first_notification_delay))); + table->addColumn(std::make_unique( + prefix + "low_flap_threshold", "Low threshold of flap detection", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, low_flap_threshold))); + table->addColumn(std::make_unique( + prefix + "high_flap_threshold", "High threshold of flap detection", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, high_flap_threshold))); + table->addColumn(std::make_unique( + prefix + "x_3d", "3D-Coordinates: X", indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, x_3d))); + table->addColumn(std::make_unique( + prefix + "y_3d", "3D-Coordinates: Y", indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, y_3d))); + table->addColumn(std::make_unique( + prefix + "z_3d", "3D-Coordinates: Z", indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, z_3d))); + table->addColumn(std::make_unique( + prefix + "latency", + "Time difference between scheduled check time and actual check time", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, latency))); + table->addColumn(std::make_unique( + prefix + "execution_time", "Time the host check needed for execution", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, execution_time))); + table->addColumn(std::make_unique( + prefix + "percent_state_change", "Percent state change", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, percent_state_change))); + + table->addColumn(std::make_unique( + prefix + "in_notification_period", + "Whether this host is currently in its notification period (0/1)", + indirect_offset, extra_offset, + DANGEROUS_OFFSETOF(host, notification_period_ptr), 0)); + table->addColumn(std::make_unique( + prefix + "in_check_period", + "Whether this host is currently in its check period (0/1)", + indirect_offset, extra_offset, + DANGEROUS_OFFSETOF(host, check_period_ptr), 0)); + table->addColumn(std::make_unique( + prefix + "in_service_period", + "Whether this host is currently in its service period (0/1)", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, custom_variables), "SERVICE_PERIOD")); + + table->addColumn(std::make_unique( + prefix + "contacts", + "A list of all contacts of this host, either direct or via a contact group", + indirect_offset, extra_offset, -1, 0)); + table->addColumn(std::make_unique( + prefix + "downtimes", + "A list of the ids of all scheduled downtimes of this host", + indirect_offset, extra_offset, -1, 0, table->core(), false, false)); + table->addColumn(std::make_unique( + prefix + "downtimes_with_info", + "A list of the all scheduled downtimes of the host with id, author and comment", + indirect_offset, extra_offset, -1, 0, table->core(), false, true)); + table->addColumn(std::make_unique( + prefix + "comments", "A list of the ids of all comments of this host", + indirect_offset, extra_offset, -1, 0, table->core(), false, false, + false)); + table->addColumn(std::make_unique( + prefix + "comments_with_info", + "A list of all comments of the host with id, author and comment", + indirect_offset, extra_offset, -1, 0, table->core(), false, true, + false)); + table->addColumn(std::make_unique( + prefix + "comments_with_extra_info", + "A list of all comments of the host with id, author, comment, entry type and entry time", + indirect_offset, extra_offset, -1, 0, table->core(), false, true, + true)); + + table->addColumn(std::make_unique( + prefix + "custom_variable_names", + "A list of the names of all custom variables", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, custom_variables))); + table->addColumn(std::make_unique( + prefix + "custom_variable_values", + "A list of the values of the custom variables", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, custom_variables))); + table->addColumn(std::make_unique( + prefix + "custom_variables", "A dictionary of the custom variables", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, custom_variables))); + + // Add direct access to the custom macro _FILENAME. In a future version of + // Livestatus this will probably be configurable so access to further custom + // variable can be added, such that those variables are presented like + // ordinary Nagios columns. + table->addColumn(std::make_unique( + prefix + "filename", "The value of the custom variable FILENAME", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, custom_variables), "FILENAME")); + + table->addColumn(std::make_unique( + prefix + "parents", "A list of all direct parents of the host", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, parent_hosts), table->core(), false)); + table->addColumn(std::make_unique( + prefix + "childs", "A list of all direct childs of the host", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, child_hosts), table->core(), false)); + + table->addColumn(std::make_unique( + prefix + "num_services", "The total number of services of the host", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num)); + table->addColumn(std::make_unique( + prefix + "worst_service_state", + "The worst soft state of all of the host's services (OK <= WARN <= UNKNOWN <= CRIT)", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::worst_state)); + table->addColumn(std::make_unique( + prefix + "num_services_ok", + "The number of the host's services with the soft state OK", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_ok)); + table->addColumn(std::make_unique( + prefix + "num_services_warn", + "The number of the host's services with the soft state WARN", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_warn)); + table->addColumn(std::make_unique( + prefix + "num_services_crit", + "The number of the host's services with the soft state CRIT", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_crit)); + table->addColumn(std::make_unique( + prefix + "num_services_unknown", + "The number of the host's services with the soft state UNKNOWN", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_unknown)); + table->addColumn(std::make_unique( + prefix + "num_services_pending", + "The number of the host's services which have not been checked yet (pending)", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_pending)); + table->addColumn(std::make_unique( + prefix + "worst_service_hard_state", + "The worst hard state of all of the host's services (OK <= WARN <= UNKNOWN <= CRIT)", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::worst_hard_state)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_ok", + "The number of the host's services with the hard state OK", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_hard_ok)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_warn", + "The number of the host's services with the hard state WARN", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_hard_warn)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_crit", + "The number of the host's services with the hard state CRIT", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_hard_crit)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_unknown", + "The number of the host's services with the hard state UNKNOWN", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), ServiceListStateColumn::Type::num_hard_unknown)); + + table->addColumn(std::make_unique( + prefix + "hard_state", + "The effective hard state of the host (eliminates a problem in hard_state)", + indirect_offset, extra_offset, -1, 0, table->core(), + HostSpecialIntColumn::Type::real_hard_state)); + table->addColumn(std::make_unique( + prefix + "pnpgraph_present", + "Whether there is a PNP4Nagios graph present for this host (-1/0/1)", + indirect_offset, extra_offset, -1, 0, table->core(), + HostSpecialIntColumn::Type::pnp_graph_present)); + table->addColumn(std::make_unique( + prefix + "mk_inventory_last", + "The timestamp of the last Check_MK HW/SW-Inventory for this host. 0 means that no inventory data is present", + indirect_offset, extra_offset, -1, 0, table->core(), + HostSpecialIntColumn::Type::mk_inventory_last)); + table->addColumn(std::make_unique( + prefix + "mk_inventory", + "The file content of the Check_MK HW/SW-Inventory", indirect_offset, + extra_offset, -1, 0, table->core()->mkInventoryPath(), "")); + table->addColumn(std::make_unique( + prefix + "mk_inventory_gz", + "The gzipped file content of the Check_MK HW/SW-Inventory", + indirect_offset, extra_offset, -1, 0, table->core()->mkInventoryPath(), + ".gz")); + table->addColumn(std::make_unique( + prefix + "structured_status", + "The file content of the structured status of the Check_MK HW/SW-Inventory", + indirect_offset, extra_offset, -1, 0, + table->core()->structuredStatusPath(), "")); + + table->addColumn(std::make_unique( + prefix + "mk_logwatch_files", + "This list of logfiles with problems fetched via mk_logwatch", + indirect_offset, extra_offset, -1, 0, table->core())); + + table->addDynamicColumn(std::make_unique( + prefix + "mk_logwatch_file", + "This contents of a logfile fetched via mk_logwatch", table->logger(), + table->core(), indirect_offset, extra_offset, -1)); + + table->addColumn(std::make_unique( + prefix + "staleness", "Staleness indicator for this host", + indirect_offset, extra_offset, -1, 0, + HostSpecialDoubleColumn::Type::staleness)); + + table->addColumn(std::make_unique( + prefix + "groups", "A list of all host groups this host is in", + indirect_offset, extra_offset, -1, + DANGEROUS_OFFSETOF(host, hostgroups_ptr), table->core())); + table->addColumn(std::make_unique( + prefix + "contact_groups", + "A list of all contact groups this host is in", indirect_offset, + extra_offset, -1, DANGEROUS_OFFSETOF(host, contact_groups))); + + table->addColumn(std::make_unique( + prefix + "services", "A list of all services of the host", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), 0)); + table->addColumn(std::make_unique( + prefix + "services_with_state", + "A list of all services of the host together with state and has_been_checked", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), 1)); + table->addColumn(std::make_unique( + prefix + "services_with_info", + "A list of all services including detailed information about each service", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), 2)); + table->addColumn(std::make_unique( + prefix + "services_with_fullstate", + "A list of all services including full state information. The list of entries can grow in future versions.", + indirect_offset, extra_offset, -1, DANGEROUS_OFFSETOF(host, services), + table->core(), 3)); + + table->addColumn(std::make_unique( + prefix + "metrics", + "A dummy column in order to be compatible with Check_MK Multisite", + indirect_offset, extra_offset, -1, 0, table->core())); +} + +void TableHosts::answerQuery(Query *query) { + // do we know the host group? + if (auto value = query->stringValueRestrictionFor("groups")) { + Debug(logger()) << "using host group index with '" << *value << "'"; + if (hostgroup *hg = + find_hostgroup(const_cast(value->c_str()))) { + for (hostsmember *mem = hg->members; mem != nullptr; + mem = mem->next) { + if (!query->processDataset(Row(mem->host_ptr))) { + break; + } + } + } + return; + } + + // no index -> linear search over all hosts + Debug(logger()) << "using full table scan"; + for (host *hst = host_list; hst != nullptr; hst = hst->next) { + if (!query->processDataset(Row(hst))) { + break; + } + } +} +bool TableHosts::isAuthorized(Row row, const contact *ctc) const { + return is_authorized_for(core(), ctc, rowData(row), nullptr); +} + +Row TableHosts::findObject(const std::string &objectspec) const { + return Row(find_host(const_cast(objectspec.c_str()))); +} diff --git a/src/TableHosts.h b/src/TableHosts.h new file mode 100644 index 0000000..3fb9770 --- /dev/null +++ b/src/TableHosts.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableHosts_h +#define TableHosts_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Row.h" +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; + +class TableHosts : public Table { +public: + explicit TableHosts(MonitoringCore *mc); + static void addColumns(Table *table, const std::string &prefix, + int indirect_offset, int extra_offset); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; + [[nodiscard]] Row findObject(const std::string &objectspec) const override; +}; + +#endif // TableHosts_h diff --git a/src/TableHostsByGroup.cc b/src/TableHostsByGroup.cc new file mode 100644 index 0000000..8e10ee6 --- /dev/null +++ b/src/TableHostsByGroup.cc @@ -0,0 +1,77 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableHostsByGroup.h" +#include "MonitoringCore.h" +#include "Query.h" +#include "Row.h" +#include "TableHostGroups.h" +#include "TableHosts.h" +#include "auth.h" +#include "nagios.h" + +extern host *host_list; +extern hostgroup *hostgroup_list; + +namespace { +struct hostbygroup { + host _host; + hostgroup *_hostgroup; +}; +} // namespace + +TableHostsByGroup::TableHostsByGroup(MonitoringCore *mc) : Table(mc) { + TableHosts::addColumns(this, "", -1, -1); + TableHostGroups::addColumns(this, "hostgroup_", + DANGEROUS_OFFSETOF(hostbygroup, _hostgroup)); +} + +std::string TableHostsByGroup::name() const { return "hostsbygroup"; } + +std::string TableHostsByGroup::namePrefix() const { return "host_"; } + +void TableHostsByGroup::answerQuery(Query *query) { + bool requires_authcheck = + query->authUser() != nullptr && + core()->groupAuthorization() == AuthorizationKind::strict; + + for (hostgroup *hg = hostgroup_list; hg != nullptr; hg = hg->next) { + if (requires_authcheck && + !is_authorized_for_host_group(core(), hg, query->authUser())) { + continue; + } + + for (hostsmember *m = hg->members; m != nullptr; m = m->next) { + hostbygroup hbg = {*m->host_ptr, hg}; + if (!query->processDataset(Row(&hbg))) { + return; + } + } + } +} + +bool TableHostsByGroup::isAuthorized(Row row, const contact *ctc) const { + return is_authorized_for(core(), ctc, &rowData(row)->_host, + nullptr); +} diff --git a/src/TableHostsByGroup.h b/src/TableHostsByGroup.h new file mode 100644 index 0000000..4e3ca0b --- /dev/null +++ b/src/TableHostsByGroup.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableHostsByGroup_h +#define TableHostsByGroup_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; +class Row; + +class TableHostsByGroup : public Table { +public: + explicit TableHostsByGroup(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; + // NOTE: We do *not* implement findObject() here, because we don't know + // which host group we should refer to: Every host can be part of many host + // groups. +}; + +#endif // TableHostsByGroup_h diff --git a/src/TableLog.cc b/src/TableLog.cc new file mode 100644 index 0000000..abdf069 --- /dev/null +++ b/src/TableLog.cc @@ -0,0 +1,208 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableLog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "Column.h" +#include "LogCache.h" +#include "LogEntry.h" +#include "Logfile.h" +#include "OffsetIntColumn.h" +#include "OffsetSStringColumn.h" +#include "OffsetStringColumn.h" +#include "OffsetTimeColumn.h" +#include "Query.h" +#include "Row.h" +#include "TableCommands.h" +#include "TableContacts.h" +#include "TableHosts.h" +#include "TableServices.h" + +#ifdef CMC +#include "cmc.h" +#else +#include "auth.h" +#include "nagios.h" +#endif + +TableLog::TableLog(MonitoringCore *mc, LogCache *log_cache) + : Table(mc), _log_cache(log_cache) { + addColumn(std::make_unique( + "time", "Time of the log event (UNIX timestamp)", -1, -1, -1, + DANGEROUS_OFFSETOF(LogEntry, _time))); + addColumn(std::make_unique( + "lineno", "The number of the line in the log file", -1, -1, -1, + DANGEROUS_OFFSETOF(LogEntry, _lineno))); + addColumn(std::make_unique( + "class", + "The class of the message as integer (0:info, 1:state, 2:program, 3:notification, 4:passive, 5:command)", + -1, -1, -1, DANGEROUS_OFFSETOF(LogEntry, _logclass))); + addColumn(std::make_unique( + "message", "The complete message line including the timestamp", -1, -1, + -1, DANGEROUS_OFFSETOF(LogEntry, _complete))); + addColumn(std::make_unique( + "type", + "The type of the message (text before the colon), the message itself for info messages", + -1, -1, -1, DANGEROUS_OFFSETOF(LogEntry, _text))); + addColumn(std::make_unique( + "options", "The part of the message after the ':'", -1, -1, -1, + DANGEROUS_OFFSETOF(LogEntry, _options))); + addColumn(std::make_unique( + "comment", "A comment field used in various message types", -1, -1, -1, + DANGEROUS_OFFSETOF(LogEntry, _comment))); + addColumn(std::make_unique( + "plugin_output", + "The output of the check, if any is associated with the message", -1, + -1, -1, DANGEROUS_OFFSETOF(LogEntry, _check_output))); + addColumn(std::make_unique( + "state", "The state of the host or service in question", -1, -1, -1, + DANGEROUS_OFFSETOF(LogEntry, _state))); + addColumn(std::make_unique( + "state_type", "The type of the state (varies on different log classes)", + -1, -1, -1, DANGEROUS_OFFSETOF(LogEntry, _state_type))); + addColumn(std::make_unique( + "attempt", "The number of the check attempt", -1, -1, -1, + DANGEROUS_OFFSETOF(LogEntry, _attempt))); + addColumn(std::make_unique( + "service_description", + "The description of the service log entry is about (might be empty)", + -1, -1, -1, DANGEROUS_OFFSETOF(LogEntry, _svc_desc))); + addColumn(std::make_unique( + "host_name", + "The name of the host the log entry is about (might be empty)", -1, -1, + -1, DANGEROUS_OFFSETOF(LogEntry, _host_name))); + addColumn(std::make_unique( + "contact_name", + "The name of the contact the log entry is about (might be empty)", -1, + -1, -1, DANGEROUS_OFFSETOF(LogEntry, _contact_name))); + addColumn(std::make_unique( + "command_name", + "The name of the command of the log entry (e.g. for notifications)", -1, + -1, -1, DANGEROUS_OFFSETOF(LogEntry, _command_name))); + + // join host and service tables + TableHosts::addColumns(this, "current_host_", + DANGEROUS_OFFSETOF(LogEntry, _host), -1); + TableServices::addColumns(this, "current_service_", + DANGEROUS_OFFSETOF(LogEntry, _service), + false /* no hosts table */); + TableContacts::addColumns(this, "current_contact_", + DANGEROUS_OFFSETOF(LogEntry, _contact)); + TableCommands::addColumns(this, "current_command_", + DANGEROUS_OFFSETOF(LogEntry, _command)); +} + +std::string TableLog::name() const { return "log"; } + +std::string TableLog::namePrefix() const { return "log_"; } + +void TableLog::answerQuery(Query *query) { + std::lock_guard lg(_log_cache->_lock); + _log_cache->update(); + if (_log_cache->begin() == _log_cache->end()) { + return; + } + + // Optimize time interval for the query. In log querys there should always + // be a time range in form of one or two filter expressions over time. We + // use that to limit the number of logfiles we need to scan and to find the + // optimal entry point into the logfile + int since = query->greatestLowerBoundFor("time").value_or(0); + int until = query->leastUpperBoundFor("time").value_or(time(nullptr)) + 1; + + // The second optimization is for log message types. We want to load only + // those log type that are queried. + auto classmask = query->valueSetLeastUpperBoundFor("class") + .value_or(~std::bitset<32>()) + .to_ulong(); + if (classmask == 0) { + return; + } + + /* This code start with the oldest log entries. I'm going + to change this and start with the newest. That way, + the Limit: header produces more reasonable results. */ + + /* NEW CODE - NEWEST FIRST */ + auto it = _log_cache->end(); // it now points beyond last log file + --it; // switch to last logfile (we have at least one) + + // Now find newest log where 'until' is contained. The problem + // here: For each logfile we only know the time of the *first* entry, + // not that of the last. + while (it != _log_cache->begin() && it->first > until) { + // while logfiles are too new go back in history + --it; + } + if (it->first > until) { + return; // all logfiles are too new + } + + while (true) { + if (!it->second->answerQueryReverse(query, since, until, classmask)) { + break; // end of time range found + } + if (it == _log_cache->begin()) { + break; // this was the oldest one + } + --it; + } +} + +bool TableLog::isAuthorized(Row row, const contact *ctc) const { + auto entry = rowData(row); + service *svc = entry->_service; + host *hst = entry->_host; + + if ((hst != nullptr) || (svc != nullptr)) { + return is_authorized_for(core(), ctc, hst, svc); + // suppress entries for messages that belong to hosts that do not exist + // anymore. + } + return !(entry->_logclass == LogEntry::Class::alert || + entry->_logclass == LogEntry::Class::hs_notification || + entry->_logclass == LogEntry::Class::passivecheck || + entry->_logclass == LogEntry::Class::alert_handlers || + entry->_logclass == LogEntry::Class::state); +} + +std::shared_ptr TableLog::column(std::string colname) const { + try { + // First try to find column in the usual way + return Table::column(colname); + } catch (const std::runtime_error &e) { + // Now try with prefix "current_", since our joined tables have this + // prefix in order to make clear that we access current and not historic + // data and in order to prevent mixing up historic and current fields + // with the same name. + return Table::column("current_" + colname); + } +} diff --git a/src/TableLog.h b/src/TableLog.h new file mode 100644 index 0000000..5de6b20 --- /dev/null +++ b/src/TableLog.h @@ -0,0 +1,57 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableLog_h +#define TableLog_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Table.h" +#include "contact_fwd.h" +class Column; +class Logfile; +class LogCache; +class MonitoringCore; +class Query; +class Row; + +class TableLog : public Table { +public: + TableLog(MonitoringCore *mc, LogCache *log_cache); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; + [[nodiscard]] std::shared_ptr column( + std::string colname) const override; + +private: + LogCache *_log_cache; + bool answerQuery(Query *, Logfile *, time_t, time_t); +}; + +#endif // TableLog_h diff --git a/src/TableServiceGroups.cc b/src/TableServiceGroups.cc new file mode 100644 index 0000000..ba0d57b --- /dev/null +++ b/src/TableServiceGroups.cc @@ -0,0 +1,150 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableServiceGroups.h" +#include +#include "Column.h" +#include "OffsetStringColumn.h" +#include "Query.h" +#include "ServiceGroupMembersColumn.h" +#include "ServiceListStateColumn.h" +#include "auth.h" +#include "nagios.h" + +/* this might be a hack (accessing Nagios' internal structures. +Ethan: please help me here: how should this be code to be +portable? */ +extern servicegroup *servicegroup_list; + +TableServiceGroups::TableServiceGroups(MonitoringCore *mc) : Table(mc) { + addColumns(this, "", -1); +} + +std::string TableServiceGroups::name() const { return "servicegroups"; } + +std::string TableServiceGroups::namePrefix() const { return "servicegroup_"; } + +// static +void TableServiceGroups::addColumns(Table *table, const std::string &prefix, + int indirect_offset) { + table->addColumn(std::make_unique( + prefix + "name", "The name of the service group", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(servicegroup, group_name))); + table->addColumn(std::make_unique( + prefix + "alias", "An alias of the service group", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(servicegroup, alias))); + table->addColumn(std::make_unique( + prefix + "notes", "Optional additional notes about the service group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(servicegroup, notes))); + table->addColumn(std::make_unique( + prefix + "notes_url", + "An optional URL to further notes on the service group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(servicegroup, notes_url))); + table->addColumn(std::make_unique( + prefix + "action_url", + "An optional URL to custom notes or actions on the service group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(servicegroup, action_url))); + table->addColumn(std::make_unique( + prefix + "members", + "A list of all members of the service group as host/service pairs", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), + table->core(), false)); + table->addColumn(std::make_unique( + prefix + "members_with_state", + "A list of all members of the service group with state and has_been_checked", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), + table->core(), true)); + + table->addColumn(std::make_unique( + prefix + "worst_service_state", + "The worst soft state of all of the groups services (OK <= WARN <= UNKNOWN <= CRIT)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), + table->core(), ServiceListStateColumn::Type::worst_state)); + table->addColumn(std::make_unique( + prefix + "num_services", "The total number of services in the group", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), + table->core(), ServiceListStateColumn::Type::num)); + table->addColumn(std::make_unique( + prefix + "num_services_ok", + "The number of services in the group that are OK", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_ok)); + table->addColumn(std::make_unique( + prefix + "num_services_warn", + "The number of services in the group that are WARN", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_warn)); + table->addColumn(std::make_unique( + prefix + "num_services_crit", + "The number of services in the group that are CRIT", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_crit)); + table->addColumn(std::make_unique( + prefix + "num_services_unknown", + "The number of services in the group that are UNKNOWN", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_unknown)); + table->addColumn(std::make_unique( + prefix + "num_services_pending", + "The number of services in the group that are PENDING", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_pending)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_ok", + "The number of services in the group that are OK", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_hard_ok)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_warn", + "The number of services in the group that are WARN", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_hard_warn)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_crit", + "The number of services in the group that are CRIT", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_hard_crit)); + table->addColumn(std::make_unique( + prefix + "num_services_hard_unknown", + "The number of services in the group that are UNKNOWN", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(servicegroup, members), table->core(), + ServiceListStateColumn::Type::num_hard_unknown)); +} + +void TableServiceGroups::answerQuery(Query *query) { + for (servicegroup *sg = servicegroup_list; sg != nullptr; sg = sg->next) { + if (!query->processDataset(Row(sg))) { + break; + } + } +} + +Row TableServiceGroups::findObject(const std::string &objectspec) const { + return Row(find_servicegroup(const_cast(objectspec.c_str()))); +} + +bool TableServiceGroups::isAuthorized(Row row, const contact *ctc) const { + return is_authorized_for_service_group(core(), rowData(row), + ctc); +} diff --git a/src/TableServiceGroups.h b/src/TableServiceGroups.h new file mode 100644 index 0000000..d978bd9 --- /dev/null +++ b/src/TableServiceGroups.h @@ -0,0 +1,50 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableServiceGroups_h +#define TableServiceGroups_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Row.h" +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; + +class TableServiceGroups : public Table { +public: + explicit TableServiceGroups(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + [[nodiscard]] Row findObject(const std::string &objectspec) const override; + bool isAuthorized(Row row, const contact * /*ctc*/) const override; + + static void addColumns(Table *table, const std::string &prefix, + int indirect_offset); +}; + +#endif // TableServiceGroups_h diff --git a/src/TableServices.cc b/src/TableServices.cc new file mode 100644 index 0000000..8d1f0fd --- /dev/null +++ b/src/TableServices.cc @@ -0,0 +1,546 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableServices.h" +#include +#include +#include +#include +#include "AttributeListAsIntColumn.h" +#include "AttributeListColumn.h" +#include "Column.h" +#include "CommentColumn.h" +#include "ContactGroupsColumn.h" +#include "CustomTimeperiodColumn.h" +#include "CustomVarsDictColumn.h" +#include "CustomVarsExplicitColumn.h" +#include "CustomVarsNamesColumn.h" +#include "CustomVarsValuesColumn.h" +#include "DowntimeColumn.h" +#include "FixedIntColumn.h" +#include "Logger.h" +#include "MetricsColumn.h" +#include "OffsetDoubleColumn.h" +#include "OffsetIntColumn.h" +#include "OffsetPerfdataColumn.h" +#include "OffsetStringColumn.h" +#include "OffsetStringServiceMacroColumn.h" +#include "OffsetTimeColumn.h" +#include "Query.h" +#include "ServiceContactsColumn.h" +#include "ServiceGroupsColumn.h" +#include "ServiceSpecialDoubleColumn.h" +#include "ServiceSpecialIntColumn.h" +#include "StringUtils.h" +#include "TableHosts.h" +#include "TimeperiodColumn.h" +#include "auth.h" +#include "nagios.h" + +extern service *service_list; + +TableServices::TableServices(MonitoringCore *mc) : Table(mc) { + addColumns(this, "", -1, true); +} + +std::string TableServices::name() const { return "services"; } + +std::string TableServices::namePrefix() const { return "service_"; } + +// static +void TableServices::addColumns(Table *table, const std::string &prefix, + int indirect_offset, bool add_hosts) { + // Es fehlen noch: double-Spalten, unsigned long spalten, etliche weniger + // wichtige Spalten und die Servicegruppen. + table->addColumn(std::make_unique( + prefix + "description", "Description of the service (also used as key)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, description))); + table->addColumn(std::make_unique( + prefix + "display_name", + "An optional display name (not used by Nagios standard web pages)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, display_name))); +#ifndef NAGIOS4 + table->addColumn(std::make_unique( + prefix + "check_command", "Nagios command used for active checks", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, service_check_command))); + table->addColumn(std::make_unique( + prefix + "check_command_expanded", + "Nagios command used for active checks with the macros expanded", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, service_check_command))); +#else + table->addColumn(std::make_unique( + prefix + "check_command", "Nagios command used for active checks", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, check_command))); + table->addColumn(std::make_unique( + prefix + "check_command_expanded", + "Nagios command used for active checks with the macros expanded", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, check_command))); +#endif + table->addColumn(std::make_unique( + prefix + "event_handler", "Nagios command used as event handler", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, event_handler))); + table->addColumn(std::make_unique( + prefix + "plugin_output", "Output of the last check plugin", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, plugin_output))); + table->addColumn(std::make_unique( + prefix + "long_plugin_output", + "Unabbreviated output of the last check plugin", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(service, long_plugin_output))); + table->addColumn(std::make_unique( + prefix + "perf_data", "Performance data of the last check plugin", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, perf_data))); + table->addColumn(std::make_unique( + prefix + "notification_period", + "The name of the notification period of the service. It this is empty, service problems are always notified.", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, notification_period))); + table->addColumn(std::make_unique( + prefix + "check_period", + "The name of the check period of the service. It this is empty, the service is always checked.", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, check_period))); + table->addColumn(std::make_unique( + prefix + "service_period", + "The name of the service period of the service", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(service, custom_variables), "SERVICE_PERIOD")); + table->addColumn(std::make_unique( + prefix + "notes", "Optional notes about the service", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, notes))); + table->addColumn(std::make_unique( + prefix + "notes_expanded", + "The notes with (the most important) macros expanded", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, notes))); + table->addColumn(std::make_unique( + prefix + "notes_url", + "An optional URL for additional notes about the service", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, notes_url))); + table->addColumn(std::make_unique( + prefix + "notes_url_expanded", + "The notes_url with (the most important) macros expanded", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, notes_url))); + table->addColumn(std::make_unique( + prefix + "action_url", + "An optional URL for actions or custom information about the service", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, action_url))); + table->addColumn(std::make_unique( + prefix + "action_url_expanded", + "The action_url with (the most important) macros expanded", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, action_url))); + table->addColumn(std::make_unique( + prefix + "icon_image", + "The name of an image to be used as icon in the web interface", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, icon_image))); + table->addColumn(std::make_unique( + prefix + "icon_image_expanded", + "The icon_image with (the most important) macros expanded", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, icon_image))); + table->addColumn(std::make_unique( + prefix + "icon_image_alt", + "An alternative text for the icon_image for browsers not displaying icons", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, icon_image_alt))); + + table->addColumn(std::make_unique( + prefix + "initial_state", "The initial state of the service", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, initial_state))); + table->addColumn(std::make_unique( + prefix + "max_check_attempts", "The maximum number of check attempts", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, max_attempts))); + table->addColumn(std::make_unique( + prefix + "current_attempt", "The number of the current check attempt", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, current_attempt))); + table->addColumn(std::make_unique( + prefix + "state", + "The current state of the service (0: OK, 1: WARN, 2: CRITICAL, 3: UNKNOWN)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, current_state))); + table->addColumn(std::make_unique( + prefix + "has_been_checked", + "Whether the service already has been checked (0/1)", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, has_been_checked))); + table->addColumn(std::make_unique( + prefix + "last_state", "The last state of the service", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, last_state))); + table->addColumn(std::make_unique( + prefix + "last_hard_state", "The last hard state of the service", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, last_hard_state))); + table->addColumn(std::make_unique( + prefix + "state_type", + "The type of the current state (0: soft, 1: hard)", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(service, state_type))); + table->addColumn(std::make_unique( + prefix + "check_type", + "The type of the last check (0: active, 1: passive)", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, check_type))); + table->addColumn(std::make_unique( + prefix + "acknowledged", + "Whether the current service problem has been acknowledged (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, problem_has_been_acknowledged))); + table->addColumn(std::make_unique( + prefix + "acknowledgement_type", + "The type of the acknownledgement (0: none, 1: normal, 2: sticky)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, acknowledgement_type))); + table->addColumn(std::make_unique( + prefix + "no_more_notifications", + "Whether to stop sending notifications (0/1)", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, no_more_notifications))); + table->addColumn(std::make_unique( + prefix + "last_time_ok", + "The last time the service was OK (Unix timestamp)", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, last_time_ok))); + table->addColumn(std::make_unique( + prefix + "last_time_warning", + "The last time the service was in WARNING state (Unix timestamp)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, last_time_warning))); + table->addColumn(std::make_unique( + prefix + "last_time_critical", + "The last time the service was CRITICAL (Unix timestamp)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, last_time_critical))); + table->addColumn(std::make_unique( + prefix + "last_time_unknown", + "The last time the service was UNKNOWN (Unix timestamp)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, last_time_unknown))); + + table->addColumn(std::make_unique( + prefix + "last_check", "The time of the last check (Unix timestamp)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, last_check))); + table->addColumn(std::make_unique( + prefix + "next_check", + "The scheduled time of the next check (Unix timestamp)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, next_check))); + table->addColumn(std::make_unique( + prefix + "last_notification", + "The time of the last notification (Unix timestamp)", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, last_notification))); + table->addColumn(std::make_unique( + prefix + "next_notification", + "The time of the next notification (Unix timestamp)", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, next_notification))); + table->addColumn(std::make_unique( + prefix + "current_notification_number", + "The number of the current notification", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, current_notification_number))); + table->addColumn(std::make_unique( + prefix + "last_state_change", + "The time of the last state change - soft or hard (Unix timestamp)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, last_state_change))); + table->addColumn(std::make_unique( + prefix + "last_hard_state_change", + "The time of the last hard state change (Unix timestamp)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, last_hard_state_change))); + table->addColumn(std::make_unique( + prefix + "scheduled_downtime_depth", + "The number of scheduled downtimes the service is currently in", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, scheduled_downtime_depth))); + table->addColumn(std::make_unique( + prefix + "is_flapping", "Whether the service is flapping (0/1)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, is_flapping))); + table->addColumn(std::make_unique( + prefix + "checks_enabled", + "Whether active checks are enabled for the service (0/1)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, checks_enabled))); +#ifndef NAGIOS4 + table->addColumn(std::make_unique( + prefix + "accept_passive_checks", + "Whether the service accepts passive checks (0/1)", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(service, accept_passive_service_checks))); +#else + table->addColumn(std::make_unique( + prefix + "accept_passive_checks", + "Whether the service accepts passive checks (0/1)", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(service, accept_passive_checks))); +#endif // NAGIOS4 + table->addColumn(std::make_unique( + prefix + "event_handler_enabled", + "Whether and event handler is activated for the service (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, event_handler_enabled))); + table->addColumn(std::make_unique( + prefix + "notifications_enabled", + "Whether notifications are enabled for the service (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, notifications_enabled))); + table->addColumn(std::make_unique( + prefix + "process_performance_data", + "Whether processing of performance data is enabled for the service (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, process_performance_data))); + table->addColumn(std::make_unique( + prefix + "is_executing", + "is there a service check currently running... (0/1)", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, is_executing))); + table->addColumn(std::make_unique( + prefix + "active_checks_enabled", + "Whether active checks are enabled for the service (0/1)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, checks_enabled))); + table->addColumn(std::make_unique( + prefix + "check_options", + "The current check option, forced, normal, freshness... (0/1)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, check_options))); + table->addColumn(std::make_unique( + prefix + "flap_detection_enabled", + "Whether flap detection is enabled for the service (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, flap_detection_enabled))); + table->addColumn(std::make_unique( + prefix + "check_freshness", + "Whether freshness checks are activated (0/1)", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, check_freshness))); +#ifndef NAGIOS4 + table->addColumn(std::make_unique( + prefix + "obsess_over_service", + "Whether 'obsess_over_service' is enabled for the service (0/1)", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, obsess_over_service))); +#else + table->addColumn(std::make_unique( + prefix + "obsess_over_service", + "Whether 'obsess_over_service' is enabled for the service (0/1)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, obsess))); +#endif // NAGIOS4 + table->addColumn(std::make_unique( + prefix + "modified_attributes", + "A bitmask specifying which attributes have been modified", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, modified_attributes))); + table->addColumn(std::make_unique( + prefix + "modified_attributes_list", + "A list of all modified attributes", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, modified_attributes))); + table->addColumn(std::make_unique( + prefix + "hard_state", + "The effective hard state of the service (eliminates a problem in hard_state)", + indirect_offset, -1, -1, 0, table->core(), + ServiceSpecialIntColumn::Type::real_hard_state)); + table->addColumn(std::make_unique( + prefix + "pnpgraph_present", + "Whether there is a PNP4Nagios graph present for this service (0/1)", + indirect_offset, -1, -1, 0, table->core(), + ServiceSpecialIntColumn::Type::pnp_graph_present)); + table->addColumn(std::make_unique( + prefix + "staleness", "The staleness indicator for this service", + indirect_offset, -1, -1, 0, + ServiceSpecialDoubleColumn::Type::staleness)); + + // columns of type double + table->addColumn(std::make_unique( + prefix + "check_interval", + "Number of basic interval lengths between two scheduled checks of the service", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, check_interval))); + table->addColumn(std::make_unique( + prefix + "retry_interval", + "Number of basic interval lengths between checks when retrying after a soft error", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, retry_interval))); + table->addColumn(std::make_unique( + prefix + "notification_interval", + "Interval of periodic notification or 0 if its off", indirect_offset, + -1, -1, DANGEROUS_OFFSETOF(service, notification_interval))); + table->addColumn(std::make_unique( + prefix + "first_notification_delay", + "Delay before the first notification", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, first_notification_delay))); + table->addColumn(std::make_unique( + prefix + "low_flap_threshold", "Low threshold of flap detection", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, low_flap_threshold))); + table->addColumn(std::make_unique( + prefix + "high_flap_threshold", "High threshold of flap detection", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, high_flap_threshold))); + table->addColumn(std::make_unique( + prefix + "latency", + "Time difference between scheduled check time and actual check time", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, latency))); + table->addColumn(std::make_unique( + prefix + "execution_time", + "Time the service check needed for execution", indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, execution_time))); + table->addColumn(std::make_unique( + prefix + "percent_state_change", "Percent state change", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, percent_state_change))); + + table->addColumn(std::make_unique( + prefix + "in_check_period", + "Whether the service is currently in its check period (0/1)", + indirect_offset, DANGEROUS_OFFSETOF(service, check_period_ptr), -1, 0)); + table->addColumn(std::make_unique( + prefix + "in_service_period", + "Whether this service is currently in its service period (0/1)", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, custom_variables), + "SERVICE_PERIOD")); + table->addColumn(std::make_unique( + prefix + "in_notification_period", + "Whether the service is currently in its notification period (0/1)", + indirect_offset, DANGEROUS_OFFSETOF(service, notification_period_ptr), + -1, 0)); + + table->addColumn(std::make_unique( + prefix + "contacts", + "A list of all contacts of the service, either direct or via a contact group", + indirect_offset, -1, -1, 0)); + table->addColumn(std::make_unique( + prefix + "downtimes", "A list of all downtime ids of the service", + indirect_offset, -1, -1, 0, table->core(), true, false)); + table->addColumn(std::make_unique( + prefix + "downtimes_with_info", + "A list of all downtimes of the service with id, author and comment", + indirect_offset, -1, -1, 0, table->core(), true, true)); + table->addColumn(std::make_unique( + prefix + "comments", "A list of all comment ids of the service", + indirect_offset, -1, -1, 0, table->core(), true, false, false)); + table->addColumn(std::make_unique( + prefix + "comments_with_info", + "A list of all comments of the service with id, author and comment", + indirect_offset, -1, -1, 0, table->core(), true, true, false)); + table->addColumn(std::make_unique( + prefix + "comments_with_extra_info", + "A list of all comments of the service with id, author, comment, entry type and entry time", + indirect_offset, -1, -1, 0, table->core(), true, true, true)); + + if (add_hosts) { + TableHosts::addColumns(table, "host_", + DANGEROUS_OFFSETOF(service, host_ptr), -1); + } + + table->addColumn(std::make_unique( + prefix + "custom_variable_names", + "A list of the names of all custom variables of the service", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, custom_variables))); + table->addColumn(std::make_unique( + prefix + "custom_variable_values", + "A list of the values of all custom variable of the service", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, custom_variables))); + table->addColumn(std::make_unique( + prefix + "custom_variables", "A dictionary of the custom variables", + indirect_offset, -1, -1, + DANGEROUS_OFFSETOF(service, custom_variables))); + + table->addColumn(std::make_unique( + prefix + "groups", "A list of all service groups the service is in", + indirect_offset, -1, -1, DANGEROUS_OFFSETOF(service, servicegroups_ptr), + table->core())); + table->addColumn(std::make_unique( + prefix + "contact_groups", + "A list of all contact groups this service is in", indirect_offset, -1, + -1, DANGEROUS_OFFSETOF(service, contact_groups))); + + table->addColumn(std::make_unique( + prefix + "metrics", + "A dummy column in order to be compatible with Check_MK Multisite", + indirect_offset, -1, -1, 0, table->core())); + table->addColumn(std::make_unique( + prefix + "cached_at", + "A dummy column in order to be compatible with Check_MK Multisite", 0)); + table->addColumn(std::make_unique( + prefix + "cache_interval", + "A dummy column in order to be compatible with Check_MK Multisite", 0)); +} + +void TableServices::answerQuery(Query *query) { + // do we know the host? + if (auto value = query->stringValueRestrictionFor("host_name")) { + Debug(logger()) << "using host name index with '" << *value << "'"; + // Older Nagios headers are not const-correct... :-P + if (host *host = find_host(const_cast(value->c_str()))) { + for (servicesmember *m = host->services; m != nullptr; + m = m->next) { + if (!query->processDataset(Row(m->service_ptr))) { + break; + } + } + return; + } + } + + // do we know the service group? + if (auto value = query->stringValueRestrictionFor("groups")) { + Debug(logger()) << "using service group index with '" << *value << "'"; + if (servicegroup *sg = + find_servicegroup(const_cast(value->c_str()))) { + for (servicesmember *m = sg->members; m != nullptr; m = m->next) { + if (!query->processDataset(Row(m->service_ptr))) { + break; + } + } + } + return; + } + + // do we know the host group? + if (auto value = query->stringValueRestrictionFor("host_groups")) { + Debug(logger()) << "using host group index with '" << *value << "'"; + if (hostgroup *hg = + find_hostgroup(const_cast(value->c_str()))) { + for (hostsmember *m = hg->members; m != nullptr; m = m->next) { + for (servicesmember *smem = m->host_ptr->services; + smem != nullptr; smem = smem->next) { + if (!query->processDataset(Row(smem->service_ptr))) { + return; + } + } + } + } + return; + } + + // no index -> iterator over *all* services + Debug(logger()) << "using full table scan"; + for (service *svc = service_list; svc != nullptr; svc = svc->next) { + if (!query->processDataset(Row(svc))) { + break; + } + } +} + +bool TableServices::isAuthorized(Row row, const contact *ctc) const { + auto svc = rowData(row); + return is_authorized_for(core(), ctc, svc->host_ptr, svc); +} + +Row TableServices::findObject(const std::string &objectspec) const { + // The protocol proposes spaces as a separator between the host name and the + // service description. That introduces the problem that host name + // containing spaces will not work. For that reason we alternatively allow a + // semicolon as a separator. + auto semicolon = objectspec.find(';'); + auto host_and_desc = + semicolon == std::string::npos + ? mk::nextField(objectspec) + : make_pair(mk::rstrip(objectspec.substr(0, semicolon)), + mk::rstrip(objectspec.substr(semicolon + 1))); + auto foo = find_service(const_cast(host_and_desc.first.c_str()), + const_cast(host_and_desc.second.c_str())); + + return Row(foo); +} diff --git a/src/TableServices.h b/src/TableServices.h new file mode 100644 index 0000000..4adbf01 --- /dev/null +++ b/src/TableServices.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableServices_h +#define TableServices_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Row.h" +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; + +class TableServices : public Table { +public: + explicit TableServices(MonitoringCore *mc); + static void addColumns(Table *table, const std::string &prefix, + int indirect_offset, bool add_hosts); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; + [[nodiscard]] Row findObject(const std::string &objectspec) const override; +}; + +#endif // TableServices_h diff --git a/src/TableServicesByGroup.cc b/src/TableServicesByGroup.cc new file mode 100644 index 0000000..eb96b1e --- /dev/null +++ b/src/TableServicesByGroup.cc @@ -0,0 +1,77 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableServicesByGroup.h" +#include "MonitoringCore.h" +#include "Query.h" +#include "Row.h" +#include "TableServiceGroups.h" +#include "TableServices.h" +#include "auth.h" +#include "nagios.h" + +extern servicegroup *servicegroup_list; + +namespace { +struct servicebygroup { + service _service; + servicegroup *_servicegroup; +}; +} // namespace + +TableServicesByGroup::TableServicesByGroup(MonitoringCore *mc) : Table(mc) { + TableServices::addColumns(this, "", -1, true); + TableServiceGroups::addColumns( + this, "servicegroup_", + DANGEROUS_OFFSETOF(servicebygroup, _servicegroup)); +} + +std::string TableServicesByGroup::name() const { return "servicesbygroup"; } + +std::string TableServicesByGroup::namePrefix() const { return "service_"; } + +void TableServicesByGroup::answerQuery(Query *query) { + bool requires_authcheck = + query->authUser() != nullptr && + core()->groupAuthorization() == AuthorizationKind::strict; + + for (servicegroup *sg = servicegroup_list; sg != nullptr; sg = sg->next) { + if (requires_authcheck && + !is_authorized_for_service_group(core(), sg, query->authUser())) { + continue; + } + + for (servicesmember *m = sg->members; m != nullptr; m = m->next) { + servicebygroup sbg = {*m->service_ptr, sg}; + if (!query->processDataset(Row(&sbg))) { + return; + } + } + } +} + +bool TableServicesByGroup::isAuthorized(Row row, const contact *ctc) const { + auto svc = &rowData(row)->_service; + return is_authorized_for(core(), ctc, svc->host_ptr, svc); +} diff --git a/src/TableServicesByGroup.h b/src/TableServicesByGroup.h new file mode 100644 index 0000000..c398f6c --- /dev/null +++ b/src/TableServicesByGroup.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableServicesByGroup_h +#define TableServicesByGroup_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; +class Row; + +class TableServicesByGroup : public Table { +public: + explicit TableServicesByGroup(MonitoringCore *mc); + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; + // NOTE: We do *not* implement findObject() here, because we don't know + // which service group we should refer to: Every service can be part of many + // service groups. +}; + +#endif // TableServicesByGroup_h diff --git a/src/TableServicesByHostGroup.cc b/src/TableServicesByHostGroup.cc new file mode 100644 index 0000000..5aff696 --- /dev/null +++ b/src/TableServicesByHostGroup.cc @@ -0,0 +1,72 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableServicesByHostGroup.h" +#include "Query.h" +#include "Row.h" +#include "TableHostGroups.h" +#include "TableServices.h" +#include "auth.h" +#include "nagios.h" + +extern hostgroup *hostgroup_list; + +namespace { +struct servicebyhostgroup { + service _service; + hostgroup *_hostgroup; +}; +} // namespace + +TableServicesByHostGroup::TableServicesByHostGroup(MonitoringCore *mc) + : Table(mc) { + TableServices::addColumns(this, "", -1, true); + TableHostGroups::addColumns( + this, "hostgroup_", DANGEROUS_OFFSETOF(servicebyhostgroup, _hostgroup)); +} + +std::string TableServicesByHostGroup::name() const { + return "servicesbyhostgroup"; +} + +std::string TableServicesByHostGroup::namePrefix() const { return "service_"; } + +void TableServicesByHostGroup::answerQuery(Query *query) { + for (hostgroup *hg = hostgroup_list; hg != nullptr; hg = hg->next) { + for (hostsmember *mem = hg->members; mem != nullptr; mem = mem->next) { + for (servicesmember *smem = mem->host_ptr->services; + smem != nullptr; smem = smem->next) { + servicebyhostgroup sbhg = {*smem->service_ptr, hg}; + if (!query->processDataset(Row(&sbhg))) { + return; + } + } + } + } +} + +bool TableServicesByHostGroup::isAuthorized(Row row, const contact *ctc) const { + auto svc = &rowData(row)->_service; + return is_authorized_for(core(), ctc, svc->host_ptr, svc); +} diff --git a/src/TableServicesByHostGroup.h b/src/TableServicesByHostGroup.h new file mode 100644 index 0000000..a95e92e --- /dev/null +++ b/src/TableServicesByHostGroup.h @@ -0,0 +1,49 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableServicesByHostGroup_h +#define TableServicesByHostGroup_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +#include "contact_fwd.h" +class MonitoringCore; +class Query; +class Row; + +class TableServicesByHostGroup : public Table { +public: + explicit TableServicesByHostGroup(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; + // NOTE: We do *not* implement findObject() here, because we don't know + // which host group we should refer to: Every service can be part of many + // host groups. +}; + +#endif // TableServicesByHostGroup_h diff --git a/src/TableStateHistory.cc b/src/TableStateHistory.cc new file mode 100644 index 0000000..1971e73 --- /dev/null +++ b/src/TableStateHistory.cc @@ -0,0 +1,912 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableStateHistory.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "HostServiceState.h" +#include "LogEntry.h" +#include "Logger.h" +#include "OffsetDoubleColumn.h" +#include "OffsetIntColumn.h" +#include "OffsetSStringColumn.h" +#include "OffsetStringColumn.h" +#include "OffsetTimeColumn.h" +#include "OringFilter.h" // IWYU pragma: keep +#include "Query.h" +#include "Row.h" +#include "StringUtils.h" +#include "TableHosts.h" +#include "TableServices.h" + +#ifdef CMC +// This seems to be an IWYU bug: If we remove the includes as suggested, we +// would do a member access on an incomplete type. +#include "Host.h" // IWYU pragma: keep +#include "Service.h" // IWYU pragma: keep +#include "Timeperiod.h" +#include "cmc.h" +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN 3 +#else +#include "auth.h" +#include "nagios.h" +#endif + +namespace { +constexpr unsigned classmask_statehist = + (1U << static_cast(LogEntry::Class::alert)) | // + (1U << static_cast(LogEntry::Class::program)) | // + (1U << static_cast(LogEntry::Class::state)) | // + (1U << static_cast(LogEntry::Class::text)); +} // namespace + +#ifndef CMC +namespace { +std::string getCustomVariable(customvariablesmember *cvm, + const std::string &name) { + for (; cvm != nullptr; cvm = cvm->next) { + if (cvm->variable_name == name) { + return cvm->variable_value == nullptr ? "" : cvm->variable_value; + } + } + return ""; +} +} // namespace +#endif + +TableStateHistory::TableStateHistory(MonitoringCore *mc, LogCache *log_cache) + : Table(mc), _log_cache(log_cache) { + addColumn(std::make_unique( + "time", "Time of the log event (seconds since 1/1/1970)", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _time))); + addColumn(std::make_unique( + "lineno", "The number of the line in the log file", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _lineno))); + addColumn(std::make_unique( + "from", "Start time of state (seconds since 1/1/1970)", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _from))); + addColumn(std::make_unique( + "until", "End time of state (seconds since 1/1/1970)", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _until))); + addColumn(std::make_unique( + "duration", "Duration of state (until - from)", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _duration))); + addColumn(std::make_unique( + "duration_part", "Duration part in regard to the query timeframe", -1, + -1, -1, DANGEROUS_OFFSETOF(HostServiceState, _duration_part))); + addColumn(std::make_unique( + "state", + "The state of the host or service in question - OK(0) / WARNING(1) / CRITICAL(2) / UNKNOWN(3) / UNMONITORED(-1)", + -1, -1, -1, DANGEROUS_OFFSETOF(HostServiceState, _state))); + addColumn(std::make_unique( + "host_down", "Shows if the host of this service is down", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _host_down))); + addColumn(std::make_unique( + "in_downtime", "Shows if the host or service is in downtime", -1, -1, + -1, DANGEROUS_OFFSETOF(HostServiceState, _in_downtime))); + addColumn(std::make_unique( + "in_host_downtime", "Shows if the host of this service is in downtime", + -1, -1, -1, DANGEROUS_OFFSETOF(HostServiceState, _in_host_downtime))); + addColumn(std::make_unique( + "is_flapping", "Shows if the host or service is flapping", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _is_flapping))); + addColumn(std::make_unique( + "in_notification_period", + "Shows if the host or service is within its notification period", -1, + -1, -1, DANGEROUS_OFFSETOF(HostServiceState, _in_notification_period))); + addColumn(std::make_unique( + "notification_period", + "The notification period of the host or service in question", -1, -1, + -1, DANGEROUS_OFFSETOF(HostServiceState, _notification_period))); + addColumn(std::make_unique( + "in_service_period", + "Shows if the host or service is within its service period", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _in_service_period))); + addColumn(std::make_unique( + "service_period", + "The service period of the host or service in question", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _service_period))); + addColumn(std::make_unique( + "debug_info", "Debug information", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _debug_info))); + addColumn(std::make_unique( + "host_name", "Host name", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _host_name))); + addColumn(std::make_unique( + "service_description", "Description of the service", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _service_description))); + addColumn(std::make_unique( + "log_output", "Logfile output relevant for this state", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _log_output))); + addColumn(std::make_unique( + "duration_ok", "OK duration of state ( until - from )", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _duration_state_OK))); + addColumn(std::make_unique( + "duration_part_ok", "OK duration part in regard to the query timeframe", + -1, -1, -1, DANGEROUS_OFFSETOF(HostServiceState, _duration_part_OK))); + + addColumn(std::make_unique( + "duration_warning", "WARNING duration of state (until - from)", -1, -1, + -1, DANGEROUS_OFFSETOF(HostServiceState, _duration_state_WARNING))); + addColumn(std::make_unique( + "duration_part_warning", + "WARNING duration part in regard to the query timeframe", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _duration_part_WARNING))); + + addColumn(std::make_unique( + "duration_critical", "CRITICAL duration of state (until - from)", -1, + -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _duration_state_CRITICAL))); + addColumn(std::make_unique( + "duration_part_critical", + "CRITICAL duration part in regard to the query timeframe", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _duration_part_CRITICAL))); + + addColumn(std::make_unique( + "duration_unknown", "UNKNOWN duration of state (until - from)", -1, -1, + -1, DANGEROUS_OFFSETOF(HostServiceState, _duration_state_UNKNOWN))); + addColumn(std::make_unique( + "duration_part_unknown", + "UNKNOWN duration part in regard to the query timeframe", -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _duration_part_UNKNOWN))); + + addColumn(std::make_unique( + "duration_unmonitored", "UNMONITORED duration of state (until - from)", + -1, -1, -1, + DANGEROUS_OFFSETOF(HostServiceState, _duration_state_UNMONITORED))); + addColumn(std::make_unique( + "duration_part_unmonitored", + "UNMONITORED duration part in regard to the query timeframe", -1, -1, + -1, DANGEROUS_OFFSETOF(HostServiceState, _duration_part_UNMONITORED))); + + // join host and service tables + TableHosts::addColumns(this, "current_host_", + DANGEROUS_OFFSETOF(HostServiceState, _host), -1); + TableServices::addColumns(this, "current_service_", + DANGEROUS_OFFSETOF(HostServiceState, _service), + false /* no hosts table */); +} + +std::string TableStateHistory::name() const { return "statehist"; } + +std::string TableStateHistory::namePrefix() const { return "statehist_"; } + +void TableStateHistory::getPreviousLogentry() { + while (_it_entries == _entries->begin()) { + // open previous logfile + if (_it_logs == _log_cache->begin()) { + return; + } + --_it_logs; + _entries = _it_logs->second->getEntriesFor(classmask_statehist); + _it_entries = _entries->end(); + } + --_it_entries; +} + +LogEntry *TableStateHistory::getNextLogentry() { + if (_it_entries != _entries->end()) { + ++_it_entries; + } + + while (_it_entries == _entries->end()) { + auto it_logs_cpy = _it_logs; + if (++it_logs_cpy == _log_cache->end()) { + return nullptr; + } + ++_it_logs; + _entries = _it_logs->second->getEntriesFor(classmask_statehist); + _it_entries = _entries->begin(); + } + return _it_entries->second.get(); +} + +namespace { +class TimeperiodTransition { +public: + explicit TimeperiodTransition(const std::string &str) { + auto fields = mk::split(str, ';'); + if (fields.size() != 3) { + throw std::invalid_argument("expected 3 arguments"); + } + _name = fields[0]; + _from = std::stoi(fields[1]); + _to = std::stoi(fields[2]); + } + + [[nodiscard]] std::string name() const { return _name; } + [[nodiscard]] int from() const { return _from; } + [[nodiscard]] int to() const { return _to; } + +private: + std::string _name; + int _from; + int _to; +}; +} // namespace + +// Create a partial filter, that contains only such filters that check +// attributes of current hosts and services + +// static +std::unique_ptr TableStateHistory::createPartialFilter( + const Query &query) { + return query.partialFilter( + "current host/service columns", [](const Column &column) { + return mk::starts_with(column.name(), "current_") || + mk::starts_with(column.name(), "host_") || + mk::starts_with(column.name(), "service_"); + }); +} + +void TableStateHistory::answerQuery(Query *query) { + auto object_filter = createPartialFilter(*query); + std::lock_guard lg(_log_cache->_lock); + _log_cache->update(); + if (_log_cache->begin() == _log_cache->end()) { + return; + } + + // This flag might be set to true by the return value of processDataset(...) + _abort_query = false; + + // Keep track of the historic state of services/hosts here + std::map state_info; + + // Store hosts/services that we have filtered out here + std::set object_blacklist; + + // Optimize time interval for the query. In log querys there should always + // be a time range in form of one or two filter expressions over time. We + // use that to limit the number of logfiles we need to scan and to find the + // optimal entry point into the logfile + if (auto glb = query->greatestLowerBoundFor("time")) { + _since = *glb; + } else { + query->invalidRequest( + "Start of timeframe required. e.g. Filter: time > 1234567890"); + return; + } + _until = query->leastUpperBoundFor("time").value_or(time(nullptr)) + 1; + + _query_timeframe = _until - _since - 1; + if (_query_timeframe == 0) { + query->invalidRequest("Query timeframe is 0 seconds"); + return; + } + + // Switch to last logfile (we have at least one) + _it_logs = _log_cache->end(); + --_it_logs; + auto newest_log = _it_logs; + + // Now find the log where 'since' starts. + while (_it_logs != _log_cache->begin() && _it_logs->first >= _since) { + --_it_logs; // go back in history + } + + // Check if 'until' is within these logfiles + if (_it_logs->first > _until) { + // All logfiles are too new, invalid timeframe + // -> No data available. Return empty result. + return; + } + + // Determine initial logentry + _entries = _it_logs->second->getEntriesFor(classmask_statehist); + if (!_entries->empty() && _it_logs != newest_log) { + _it_entries = _entries->end(); + // Check last entry. If it's younger than _since -> use this logfile too + if (--_it_entries != _entries->begin()) { + if (_it_entries->second->_time >= _since) { + _it_entries = _entries->begin(); + } + } + } else { + _it_entries = _entries->begin(); + } + + // From now on use getPreviousLogentry() / getNextLogentry() + bool only_update = true; + bool in_nagios_initial_states = false; + + while (LogEntry *entry = getNextLogentry()) { + if (_abort_query) { + break; + } + + if (entry->_time >= _until) { + getPreviousLogentry(); + break; + } + if (only_update && entry->_time >= _since) { + // Reached start of query timeframe. From now on let's produce real + // output. Update _from time of every state entry + for (auto &it_hst : state_info) { + it_hst.second->_from = _since; + it_hst.second->_until = _since; + } + only_update = false; + } + + if (in_nagios_initial_states && + !(entry->_type == LogEntryType::state_service_initial || + entry->_type == LogEntryType::state_host_initial)) { + // Set still unknown hosts / services to unmonitored + for (auto &it_hst : state_info) { + HostServiceState *hst = it_hst.second; + if (hst->_may_no_longer_exist) { + hst->_has_vanished = true; + } + } + in_nagios_initial_states = false; + } + + HostServiceKey key = nullptr; + bool is_service = false; + switch (entry->_type) { + case LogEntryType::none: + case LogEntryType::core_starting: + case LogEntryType::core_stopping: + case LogEntryType::log_version: + case LogEntryType::acknowledge_alert_host: + case LogEntryType::acknowledge_alert_service: + break; + case LogEntryType::alert_service: + case LogEntryType::state_service: + case LogEntryType::state_service_initial: + case LogEntryType::downtime_alert_service: + case LogEntryType::flapping_service: + key = entry->_service; + is_service = true; + // fall-through + case LogEntryType::alert_host: + case LogEntryType::state_host: + case LogEntryType::state_host_initial: + case LogEntryType::downtime_alert_host: + case LogEntryType::flapping_host: { + if (!is_service) { + key = entry->_host; + } + + if (key == nullptr) { + continue; + } + + if (object_blacklist.find(key) != object_blacklist.end()) { + // Host/Service is not needed for this query and has already + // been filtered out. + continue; + } + + // Find state object for this host/service + HostServiceState *state; + auto it_hst = state_info.find(key); + if (it_hst == state_info.end()) { + // Create state object that we also need for filtering right + // now + state = new HostServiceState(); + state->_is_host = entry->_svc_desc.empty(); + state->_host = entry->_host; + state->_service = entry->_service; +#ifdef CMC + state->_host_name = entry->_host->name(); + state->_service_description = entry->_service == nullptr + ? "" + : entry->_service->name(); +#else + state->_host_name = entry->_host->name; + state->_service_description = + entry->_service == nullptr + ? "" + : entry->_service->description; +#endif + + // No state found. Now check if this host/services is + // filtered out. Note: we currently do not filter out hosts + // since they might be needed for service states + if (!entry->_svc_desc.empty()) { + if (!object_filter->accepts(Row(state), + query->authUser(), + query->timezoneOffset())) { + object_blacklist.insert(key); + delete state; + continue; + } + } + + // Host/Service relations + if (state->_is_host) { + for (auto &it_inh : state_info) { + if (it_inh.second->_host == state->_host) { + state->_services.push_back(it_inh.second); + } + } + } else { + auto it_inh = state_info.find(state->_host); + if (it_inh != state_info.end()) { + it_inh->second->_services.push_back(state); + } + } + + // Store this state object for tracking state transitions + state_info.emplace(key, state); + state->_from = _since; + + // Get notification period of host/service + // If this host/service is no longer availabe in nagios -> + // set to "" + if (state->_service != nullptr) { +#ifdef CMC + state->_notification_period = + state->_service->notificationPeriod()->name(); +#else + auto np = state->_service->notification_period; + state->_notification_period = np == nullptr ? "" : np; +#endif + } else if (state->_host != nullptr) { +#ifdef CMC + state->_notification_period = + state->_host->notificationPeriod()->name(); +#else + auto np = state->_host->notification_period; + state->_notification_period = np == nullptr ? "" : np; +#endif + } else { + state->_notification_period = ""; + } + + // Same for service period. For Nagios this is a bit + // different, since this is no native field but just a + // custom variable + if (state->_service != nullptr) { +#ifdef CMC + state->_service_period = + state->_service->servicePeriod()->name(); +#else + state->_service_period = + getCustomVariable(state->_service->custom_variables, + "SERVICE_PERIOD"); +#endif + } else if (state->_host != nullptr) { +#ifdef CMC + state->_service_period = + state->_host->servicePeriod()->name(); +#else + state->_service_period = getCustomVariable( + state->_host->custom_variables, "SERVICE_PERIOD"); +#endif + } else { + state->_service_period = ""; + } + + // Determine initial in_notification_period status + auto tmp_period = + _notification_periods.find(state->_notification_period); + if (tmp_period != _notification_periods.end()) { + state->_in_notification_period = tmp_period->second; + } else { + state->_in_notification_period = 1; + } + + // Same for service period + tmp_period = + _notification_periods.find(state->_service_period); + if (tmp_period != _notification_periods.end()) { + state->_in_service_period = tmp_period->second; + } else { + state->_in_service_period = 1; + } + + // If this key is a service try to find its host and apply + // its _in_host_downtime and _host_down parameters + if (!state->_is_host) { + auto my_host = state_info.find(state->_host); + if (my_host != state_info.end()) { + state->_in_host_downtime = + my_host->second->_in_host_downtime; + state->_host_down = my_host->second->_host_down; + } + } + + // Log UNMONITORED state if this host or service just + // appeared within the query timeframe + // It gets a grace period of ten minutes (nagios startup) + if (!only_update && entry->_time - _since > 60 * 10) { + state->_debug_info = "UNMONITORED "; + state->_state = -1; + } + } else { + state = it_hst->second; + } + + int state_changed = + updateHostServiceState(query, entry, state, only_update); + // Host downtime or state changes also affect its services + if (entry->_type == LogEntryType::alert_host || + entry->_type == LogEntryType::state_host || + entry->_type == LogEntryType::downtime_alert_host) { + if (state_changed != 0) { + for (auto &_service : state->_services) { + updateHostServiceState(query, entry, _service, + only_update); + } + } + } + break; + } + case LogEntryType::timeperiod_transition: { + try { + TimeperiodTransition tpt(entry->_options); + _notification_periods[tpt.name()] = tpt.to(); + for (auto &it_hst : state_info) { + updateHostServiceState(query, entry, it_hst.second, + only_update); + } + } catch (const std::logic_error &e) { + Warning(logger()) + << "Error: Invalid syntax of TIMEPERIOD TRANSITION: " + << entry->_complete; + } + break; + } + case LogEntryType::log_initial_states: { + // This feature is only available if log_initial_states is set + // to 1. If log_initial_states is set, each nagios startup logs + // the initial states of all known hosts and services. Therefore + // we can detect if a host is no longer available after a nagios + // startup. If it still exists an INITIAL HOST/SERVICE state + // entry will follow up shortly. + for (auto &it_hst : state_info) { + if (!it_hst.second->_has_vanished) { + it_hst.second->_last_known_time = entry->_time; + it_hst.second->_may_no_longer_exist = true; + } + } + in_nagios_initial_states = true; + break; + } + } + } + + // Create final reports + auto it_hst = state_info.begin(); + if (!_abort_query) { + while (it_hst != state_info.end()) { + HostServiceState *hst = it_hst->second; + + // No trace since the last two nagios startup -> host/service has + // vanished + if (hst->_may_no_longer_exist) { + // Log last known state up to nagios restart + hst->_time = hst->_last_known_time; + hst->_until = hst->_last_known_time; + process(query, hst); + + // Set absent state + hst->_state = -1; + hst->_debug_info = "UNMONITORED"; + hst->_log_output = ""; + } + + hst->_time = _until - 1; + hst->_until = hst->_time; + + process(query, hst); + ++it_hst; + } + } + + // Cleanup ! + it_hst = state_info.begin(); + while (it_hst != state_info.end()) { + delete it_hst->second; + ++it_hst; + } + state_info.clear(); + object_blacklist.clear(); +} + +int TableStateHistory::updateHostServiceState(Query *query, + const LogEntry *entry, + HostServiceState *hs_state, + const bool only_update) { + int state_changed = 1; + + // Revive host / service if it was unmonitored + if (entry->_type != LogEntryType::timeperiod_transition && + hs_state->_has_vanished) { + hs_state->_time = hs_state->_last_known_time; + hs_state->_until = hs_state->_last_known_time; + if (!only_update) { + process(query, hs_state); + } + + hs_state->_may_no_longer_exist = false; + hs_state->_has_vanished = false; + // Set absent state + hs_state->_state = -1; + hs_state->_debug_info = "UNMONITORED"; + hs_state->_in_downtime = 0; + hs_state->_in_notification_period = 0; + hs_state->_in_service_period = 0; + hs_state->_is_flapping = 0; + hs_state->_log_output = ""; + + // Apply latest notification period information and set the host_state + // to unmonitored + auto it_status = + _notification_periods.find(hs_state->_notification_period); + if (it_status != _notification_periods.end()) { + hs_state->_in_notification_period = it_status->second; + } else { + // No notification period information available -> within + // notification period + hs_state->_in_notification_period = 1; + } + + // Same for service period + it_status = _notification_periods.find(hs_state->_service_period); + if (it_status != _notification_periods.end()) { + hs_state->_in_service_period = it_status->second; + } else { + // No service period information available -> within service period + hs_state->_in_service_period = 1; + } + } + + // Update basic information + hs_state->_time = entry->_time; + hs_state->_lineno = entry->_lineno; + hs_state->_until = entry->_time; + + // A timeperiod entry never brings an absent host or service into + // existence.. + if (entry->_type != LogEntryType::timeperiod_transition) { + hs_state->_may_no_longer_exist = false; + } + + switch (entry->_type) { + case LogEntryType::none: + case LogEntryType::core_starting: + case LogEntryType::core_stopping: + case LogEntryType::log_version: + case LogEntryType::log_initial_states: + case LogEntryType::acknowledge_alert_host: + case LogEntryType::acknowledge_alert_service: + break; + case LogEntryType::state_host: + case LogEntryType::state_host_initial: + case LogEntryType::alert_host: { + if (hs_state->_is_host) { + if (hs_state->_state != entry->_state) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_state = entry->_state; + hs_state->_host_down = static_cast(entry->_state > 0); + hs_state->_debug_info = "HOST STATE"; + } else { + state_changed = 0; + } + } else if (hs_state->_host_down != + static_cast(entry->_state > 0)) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_host_down = static_cast(entry->_state > 0); + hs_state->_debug_info = "SVC HOST STATE"; + } + break; + } + case LogEntryType::state_service: + case LogEntryType::state_service_initial: + case LogEntryType::alert_service: { + if (hs_state->_state != entry->_state) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_debug_info = "SVC ALERT"; + hs_state->_state = entry->_state; + } + break; + } + case LogEntryType::downtime_alert_host: { + int downtime_active = + mk::starts_with(entry->_state_type, "STARTED") ? 1 : 0; + + if (hs_state->_in_host_downtime != downtime_active) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_debug_info = + hs_state->_is_host ? "HOST DOWNTIME" : "SVC HOST DOWNTIME"; + hs_state->_in_host_downtime = downtime_active; + if (hs_state->_is_host) { + hs_state->_in_downtime = downtime_active; + } + } else { + state_changed = 0; + } + break; + } + case LogEntryType::downtime_alert_service: { + int downtime_active = + mk::starts_with(entry->_state_type, "STARTED") ? 1 : 0; + if (hs_state->_in_downtime != downtime_active) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_debug_info = "DOWNTIME SERVICE"; + hs_state->_in_downtime = downtime_active; + } + break; + } + case LogEntryType::flapping_host: + case LogEntryType::flapping_service: { + int flapping_active = + mk::starts_with(entry->_state_type, "STARTED") ? 1 : 0; + if (hs_state->_is_flapping != flapping_active) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_debug_info = "FLAPPING "; + hs_state->_is_flapping = flapping_active; + } else { + state_changed = 0; + } + break; + } + case LogEntryType::timeperiod_transition: { + try { + TimeperiodTransition tpt(entry->_options); + // if no _host pointer is available the initial status of + // _in_notification_period (1) never changes + if (hs_state->_host != nullptr && + tpt.name() == hs_state->_notification_period) { + if (tpt.to() != hs_state->_in_notification_period) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_debug_info = "TIMEPERIOD "; + hs_state->_in_notification_period = tpt.to(); + } + } + // same for service period + if (hs_state->_host != nullptr && + tpt.name() == hs_state->_service_period) { + if (tpt.to() != hs_state->_in_service_period) { + if (!only_update) { + process(query, hs_state); + } + hs_state->_debug_info = "TIMEPERIOD "; + hs_state->_in_service_period = tpt.to(); + } + } + } catch (const std::logic_error &e) { + Warning(logger()) + << "Error: Invalid syntax of TIMEPERIOD TRANSITION: " + << entry->_complete; + } + break; + } + } + + if (entry->_type != LogEntryType::timeperiod_transition) { + if ((entry->_type == LogEntryType::state_host_initial || + entry->_type == LogEntryType::state_service_initial) && + entry->_check_output == "(null)") { + hs_state->_log_output = ""; + } else { + hs_state->_log_output = entry->_check_output; + } + } + + return state_changed; +} + +void TableStateHistory::process(Query *query, HostServiceState *hs_state) { + hs_state->_duration = hs_state->_until - hs_state->_from; + hs_state->_duration_part = static_cast(hs_state->_duration) / + static_cast(_query_timeframe); + + hs_state->_duration_state_UNMONITORED = 0; + hs_state->_duration_part_UNMONITORED = 0; + + hs_state->_duration_state_OK = 0; + hs_state->_duration_part_OK = 0; + + hs_state->_duration_state_WARNING = 0; + hs_state->_duration_part_WARNING = 0; + + hs_state->_duration_state_CRITICAL = 0; + hs_state->_duration_part_CRITICAL = 0; + + hs_state->_duration_state_UNKNOWN = 0; + hs_state->_duration_part_UNKNOWN = 0; + + switch (hs_state->_state) { + case -1: + hs_state->_duration_state_UNMONITORED = hs_state->_duration; + hs_state->_duration_part_UNMONITORED = hs_state->_duration_part; + break; + case STATE_OK: + hs_state->_duration_state_OK = hs_state->_duration; + hs_state->_duration_part_OK = hs_state->_duration_part; + break; + case STATE_WARNING: + hs_state->_duration_state_WARNING = hs_state->_duration; + hs_state->_duration_part_WARNING = hs_state->_duration_part; + break; + case STATE_CRITICAL: + hs_state->_duration_state_CRITICAL = hs_state->_duration; + hs_state->_duration_part_CRITICAL = hs_state->_duration_part; + break; + case STATE_UNKNOWN: + hs_state->_duration_state_UNKNOWN = hs_state->_duration; + hs_state->_duration_part_UNKNOWN = hs_state->_duration_part; + break; + default: + break; + } + + // if (hs_state->_duration > 0) + _abort_query = !query->processDataset(Row(hs_state)); + + hs_state->_from = hs_state->_until; +} + +bool TableStateHistory::isAuthorized(Row row, const contact *ctc) const { + auto entry = rowData(row); + service *svc = entry->_service; + host *hst = entry->_host; + return (hst != nullptr || svc != nullptr) && + is_authorized_for(core(), ctc, hst, svc); +} + +std::shared_ptr TableStateHistory::column(std::string colname) const { + try { + // First try to find column in the usual way + return Table::column(colname); + } catch (const std::runtime_error &e) { + // Now try with prefix "current_", since our joined tables have this + // prefix in order to make clear that we access current and not historic + // data and in order to prevent mixing up historic and current fields + // with the same name. + return Table::column("current_" + colname); + } +} diff --git a/src/TableStateHistory.h b/src/TableStateHistory.h new file mode 100644 index 0000000..78188f1 --- /dev/null +++ b/src/TableStateHistory.h @@ -0,0 +1,86 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableStateHistory_h +#define TableStateHistory_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "LogCache.h" +#include "Logfile.h" +#include "Table.h" +class Column; +class Filter; +class HostServiceState; +class LogEntry; +class MonitoringCore; +class Query; +class Row; + +#ifdef CMC +#include "cmc.h" +#else +#include "contact_fwd.h" +#endif + +class TableStateHistory : public Table { +public: + TableStateHistory(MonitoringCore *mc, LogCache *log_cache); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + bool isAuthorized(Row row, const contact *ctc) const override; + [[nodiscard]] std::shared_ptr column( + std::string colname) const override; + static std::unique_ptr createPartialFilter(const Query &query); + +protected: + bool _abort_query; + +private: + LogCache *_log_cache; + + int _query_timeframe; + int _since; + int _until; + + // Notification periods information, name: active(1)/inactive(0) + std::map _notification_periods; + + // Helper functions to traverse through logfiles + logfiles_t::const_iterator _it_logs; + const logfile_entries_t *_entries; + logfile_entries_t::const_iterator _it_entries; + + void getPreviousLogentry(); + LogEntry *getNextLogentry(); + void process(Query *query, HostServiceState *hs_state); + int updateHostServiceState(Query *query, const LogEntry *entry, + HostServiceState *hs_state, bool only_update); +}; + +#endif // TableStateHistory_h diff --git a/src/TableStatus.cc b/src/TableStatus.cc new file mode 100644 index 0000000..b09aebc --- /dev/null +++ b/src/TableStatus.cc @@ -0,0 +1,259 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableStatus.h" +#include +#include +#include +#include "AtomicInt32PointerColumn.h" +#include "Column.h" +#include "DoublePointerColumn.h" +#include "IntPointerColumn.h" +#include "Query.h" +#include "Row.h" +#include "StatusSpecialIntColumn.h" +#include "StringPointerColumn.h" +#include "TimePointerColumn.h" +#include "global_counters.h" +#include "nagios.h" + +extern time_t program_start; +extern int nagios_pid; +#ifndef NAGIOS4 +extern time_t last_command_check; +#endif +extern time_t last_log_rotation; +extern int enable_notifications; +extern int execute_service_checks; +extern int accept_passive_service_checks; +extern int execute_host_checks; +extern int accept_passive_host_checks; +extern int enable_event_handlers; +extern int obsess_over_services; +extern int obsess_over_hosts; +extern int check_service_freshness; +extern int check_host_freshness; +extern int enable_flap_detection; +extern int process_performance_data; +extern int check_external_commands; +extern int num_cached_log_messages; +extern int interval_length; +extern int g_num_hosts; +extern int g_num_services; +extern int g_livestatus_threads; +extern int g_num_queued_connections; +extern std::atomic_int32_t g_livestatus_active_connections; + +#ifndef NAGIOS4 +extern circular_buffer external_command_buffer; +extern int external_command_buffer_slots; +#else +// TODO: check if this data is available in nagios_squeue +namespace { +time_t dummy_time = 0; +int dummy_int = 0; +} // namespace +#endif // NAGIOS4 + +TableStatus::TableStatus(MonitoringCore *mc) : Table(mc) { + addCounterColumns("neb_callbacks", "NEB callbacks", Counter::neb_callbacks); + addCounterColumns("requests", "requests to Livestatus", Counter::requests); + addCounterColumns("connections", "client connections to Livestatus", + Counter::connections); + addCounterColumns("service_checks", "completed service checks", + Counter::service_checks); + addCounterColumns("host_checks", "host checks", Counter::host_checks); + addCounterColumns("forks", "process creations", Counter::forks); + addCounterColumns("log_messages", "new log messages", + Counter::log_messages); + addCounterColumns("external_commands", "external commands", + Counter::commands); + addCounterColumns("livechecks", "checks executed via livecheck", + Counter::livechecks); + addCounterColumns( + "livecheck_overflows", + "times a check could not be executed because no livecheck helper was free", + Counter::livecheck_overflows); + + // Nagios program status data + addColumn(std::make_unique( + "nagios_pid", "The process ID of the Nagios main process", + &nagios_pid)); + addColumn(std::make_unique( + "enable_notifications", + "Whether notifications are enabled in general (0/1)", + &enable_notifications)); + addColumn(std::make_unique( + "execute_service_checks", + "Whether active service checks are activated in general (0/1)", + &execute_service_checks)); + addColumn(std::make_unique( + "accept_passive_service_checks", + "Whether passive service checks are activated in general (0/1)", + &accept_passive_service_checks)); + addColumn(std::make_unique( + "execute_host_checks", + "Whether host checks are executed in general (0/1)", + &execute_host_checks)); + addColumn(std::make_unique( + "accept_passive_host_checks", + "Whether passive host checks are accepted in general (0/1)", + &accept_passive_host_checks)); + addColumn(std::make_unique( + "enable_event_handlers", + "Whether event handlers are activated in general (0/1)", + &enable_event_handlers)); + addColumn(std::make_unique( + "obsess_over_services", + "Whether Nagios will obsess over service checks and run the ocsp_command (0/1)", + &obsess_over_services)); + addColumn(std::make_unique( + "obsess_over_hosts", + "Whether Nagios will obsess over host checks (0/1)", + &obsess_over_hosts)); + addColumn(std::make_unique( + "check_service_freshness", + "Whether service freshness checking is activated in general (0/1)", + &check_service_freshness)); + addColumn(std::make_unique( + "check_host_freshness", + "Whether host freshness checking is activated in general (0/1)", + &check_host_freshness)); + addColumn(std::make_unique( + "enable_flap_detection", + "Whether flap detection is activated in general (0/1)", + &enable_flap_detection)); + addColumn(std::make_unique( + "process_performance_data", + "Whether processing of performance data is activated in general (0/1)", + &process_performance_data)); + addColumn(std::make_unique( + "check_external_commands", + "Whether Nagios checks for external commands at its command pipe (0/1)", + &check_external_commands)); + addColumn(std::make_unique( + "program_start", "The time of the last program start as UNIX timestamp", + &program_start)); +#ifndef NAGIOS4 + addColumn(std::make_unique( + "last_command_check", + "The time of the last check for a command as UNIX timestamp", + &last_command_check)); +#else + addColumn(std::make_unique( + "last_command_check", + "The time of the last check for a command as UNIX timestamp (placeholder)", + &dummy_time)); +#endif // NAGIOS4 + addColumn(std::make_unique( + "last_log_rotation", "Time time of the last log file rotation", + &last_log_rotation)); + addColumn(std::make_unique( + "interval_length", "The default interval length from nagios.cfg", + &interval_length)); + + addColumn(std::make_unique( + "num_hosts", "The total number of hosts", &g_num_hosts)); + addColumn(std::make_unique( + "num_services", "The total number of services", &g_num_services)); + + addColumn(std::make_unique( + "program_version", "The version of the monitoring daemon", + get_program_version())); + +// External command buffer +#ifndef NAGIOS4 + addColumn(std::make_unique( + "external_command_buffer_slots", + "The size of the buffer for the external commands", + &external_command_buffer_slots)); + addColumn(std::make_unique( + "external_command_buffer_usage", + "The number of slots in use of the external command buffer", + &(external_command_buffer.items))); + addColumn(std::make_unique( + "external_command_buffer_max", + "The maximum number of slots used in the external command buffer", + &(external_command_buffer.high))); +#else + addColumn(std::make_unique( + "external_command_buffer_slots", + "The size of the buffer for the external commands (placeholder)", + &dummy_int)); + addColumn(std::make_unique( + "external_command_buffer_usage", + "The number of slots in use of the external command buffer (placeholder)", + &dummy_int)); + addColumn(std::make_unique( + "external_command_buffer_max", + "The maximum number of slots used in the external command buffer (placeholder)", + &dummy_int)); +#endif // NAGIOS4 + + // Livestatus' own status + addColumn(std::make_unique( + "cached_log_messages", + "The current number of log messages MK Livestatus keeps in memory", + &num_cached_log_messages)); + addColumn(std::make_unique( + "livestatus_version", "The version of the MK Livestatus module", + VERSION)); + addColumn(std::make_unique( + "livestatus_active_connections", + "The current number of active connections to MK Livestatus", + &g_livestatus_active_connections)); + addColumn(std::make_unique( + "livestatus_queued_connections", + "The current number of queued connections to MK Livestatus (that wait for a free thread)", + &g_num_queued_connections)); + addColumn(std::make_unique( + "livestatus_threads", + "The maximum number of connections to MK Livestatus that can be handled in parallel", + &g_livestatus_threads)); + + // Special stuff for Check_MK + addColumn(std::make_unique( + "mk_inventory_last", + "The timestamp of the last time a host has been inventorized by Check_MK HW/SW-Inventory", + -1, -1, -1, 0, mc, StatusSpecialIntColumn::Type::mk_inventory_last)); +} + +void TableStatus::addCounterColumns(const std::string &name, + const std::string &description, + Counter which) { + addColumn(std::make_unique( + name, "The number of " + description + " since program start", + counterAddress(which))); + addColumn(std::make_unique( + name + "_rate", "The averaged number of " + description + " per second", + counterRateAddress(which))); +} + +std::string TableStatus::name() const { return "status"; } + +std::string TableStatus::namePrefix() const { return "status_"; } + +void TableStatus::answerQuery(Query *query) { + query->processDataset(Row(this)); +} diff --git a/src/TableStatus.h b/src/TableStatus.h new file mode 100644 index 0000000..e270587 --- /dev/null +++ b/src/TableStatus.h @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableStatus_h +#define TableStatus_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +#include "global_counters.h" +class MonitoringCore; +class Query; + +class TableStatus : public Table { +public: + explicit TableStatus(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; + +private: + void addCounterColumns(const std::string &name, + const std::string &description, Counter which); +}; + +#endif // TableStatus_h diff --git a/src/TableTimeperiods.cc b/src/TableTimeperiods.cc new file mode 100644 index 0000000..eeb216e --- /dev/null +++ b/src/TableTimeperiods.cc @@ -0,0 +1,58 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TableTimeperiods.h" +#include +#include "Column.h" +#include "OffsetStringColumn.h" +#include "Query.h" +#include "Row.h" +#include "TimeperiodColumn.h" +#include "nagios.h" + +extern timeperiod *timeperiod_list; + +TableTimeperiods::TableTimeperiods(MonitoringCore *mc) : Table(mc) { + addColumn(std::make_unique( + "name", "The name of the timeperiod", -1, -1, -1, + DANGEROUS_OFFSETOF(timeperiod, name))); + addColumn(std::make_unique( + "alias", "The alias of the timeperiod", -1, -1, -1, + DANGEROUS_OFFSETOF(timeperiod, alias))); + addColumn(std::make_unique( + "in", "Wether we are currently in this period (0/1)", -1, -1, -1, 0)); + // TODO(mk): add days and exceptions +} + +std::string TableTimeperiods::name() const { return "timeperiods"; } + +std::string TableTimeperiods::namePrefix() const { return "timeperiod_"; } + +void TableTimeperiods::answerQuery(Query *query) { + for (timeperiod *tp = timeperiod_list; tp != nullptr; tp = tp->next) { + if (!query->processDataset(Row(tp))) { + break; + } + } +} diff --git a/src/TableTimeperiods.h b/src/TableTimeperiods.h new file mode 100644 index 0000000..9f23774 --- /dev/null +++ b/src/TableTimeperiods.h @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TableTimeperiods_h +#define TableTimeperiods_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Table.h" +class MonitoringCore; +class Query; + +class TableTimeperiods : public Table { +public: + explicit TableTimeperiods(MonitoringCore *mc); + + [[nodiscard]] std::string name() const override; + [[nodiscard]] std::string namePrefix() const override; + void answerQuery(Query *query) override; +}; + +#endif // TableTimeperiods_h diff --git a/src/TimeAggregator.h b/src/TimeAggregator.h new file mode 100644 index 0000000..d1d2d90 --- /dev/null +++ b/src/TimeAggregator.h @@ -0,0 +1,56 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TimeAggregator_h +#define TimeAggregator_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Aggregator.h" +#include "TimeColumn.h" +#include "contact_fwd.h" +class Row; +class RowRenderer; + +class TimeAggregator : public Aggregator { +public: + TimeAggregator(const AggregationFactory &factory, const TimeColumn *column) + : _aggregation(factory()), _column(column) {} + + void consume(Row row, const contact * /*auth_user*/, + std::chrono::seconds timezone_offset) override { + _aggregation->update(std::chrono::system_clock::to_time_t( + _column->getValue(row, timezone_offset))); + } + + void output(RowRenderer &r) const override { + r.output(_aggregation->value()); + } + +private: + std::unique_ptr _aggregation; + const TimeColumn *const _column; +}; + +#endif // TimeAggregator_h diff --git a/src/TimeColumn.cc b/src/TimeColumn.cc new file mode 100644 index 0000000..8b1d62c --- /dev/null +++ b/src/TimeColumn.cc @@ -0,0 +1,53 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TimeColumn.h" +#include +#include "Aggregator.h" +#include "Filter.h" +#include "Renderer.h" +#include "Row.h" +#include "TimeAggregator.h" +#include "TimeFilter.h" + +void TimeColumn::output(Row row, RowRenderer &r, const contact * /*auth_user*/, + std::chrono::seconds timezone_offset) const { + r.output(getValue(row, timezone_offset)); +} + +std::unique_ptr TimeColumn::createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const { + return std::make_unique(kind, *this, relOp, value); +} + +std::unique_ptr TimeColumn::createAggregator( + AggregationFactory factory) const { + return std::make_unique(factory, this); +} + +std::chrono::system_clock::time_point TimeColumn::getValue( + Row row, std::chrono::seconds timezone_offset) const { + return getRawValue(row) + timezone_offset; +} diff --git a/src/TimeColumn.h b/src/TimeColumn.h new file mode 100644 index 0000000..0364410 --- /dev/null +++ b/src/TimeColumn.h @@ -0,0 +1,68 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TimeColumn_h +#define TimeColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include "Column.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Aggregator; +class Row; +class RowRenderer; + +class TimeColumn : public Column { +public: + TimeColumn(const std::string &name, const std::string &description, + int indirect_offset, int extra_offset, int extra_extra_offset, + int offset) + : Column(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + + [[nodiscard]] ColumnType type() const override { return ColumnType::time; } + + void output(Row row, RowRenderer &r, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr createFilter( + Filter::Kind kind, RelationalOperator relOp, + const std::string &value) const override; + + [[nodiscard]] std::unique_ptr createAggregator( + AggregationFactory factory) const override; + + [[nodiscard]] std::chrono::system_clock::time_point getValue( + Row row, std::chrono::seconds timezone_offset) const; + +private: + [[nodiscard]] virtual std::chrono::system_clock::time_point getRawValue( + Row row) const = 0; +}; + +#endif // TimeColumn_h diff --git a/src/TimeFilter.cc b/src/TimeFilter.cc new file mode 100644 index 0000000..b37b7f1 --- /dev/null +++ b/src/TimeFilter.cc @@ -0,0 +1,150 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TimeFilter.h" +#include +#include "Filter.h" +#include "Row.h" +#include "TimeColumn.h" + +TimeFilter::TimeFilter(Kind kind, const TimeColumn &column, + RelationalOperator relOp, const std::string &value) + : ColumnFilter(kind, column, relOp, value) + , _column(column) + , _ref_value(atoi(value.c_str())) {} + +namespace { +bool eval(int32_t x, RelationalOperator op, int32_t y) { + switch (op) { + case RelationalOperator::equal: + return x == y; + case RelationalOperator::not_equal: + return x != y; + case RelationalOperator::matches: // superset + return (x & y) == y; + case RelationalOperator::doesnt_match: // not superset + return (x & y) != y; + case RelationalOperator::equal_icase: // subset + return (x & y) == x; + case RelationalOperator::not_equal_icase: // not subset + return (x & y) != x; + case RelationalOperator::matches_icase: // contains any + return (x & y) != 0; + case RelationalOperator::doesnt_match_icase: // contains none of + return (x & y) == 0; + case RelationalOperator::less: + return x < y; + case RelationalOperator::greater_or_equal: + return x >= y; + case RelationalOperator::greater: + return x > y; + case RelationalOperator::less_or_equal: + return x <= y; + } + return false; +} +} // namespace + +bool TimeFilter::accepts(Row row, const contact * /*auth_user*/, + std::chrono::seconds timezone_offset) const { + return eval(std::chrono::system_clock::to_time_t( + _column.getValue(row, timezone_offset)), + oper(), _ref_value); +} + +std::optional TimeFilter::greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + if (column_name != columnName()) { + return {}; // wrong column + } + int32_t ref_value = _ref_value - timezone_offset.count(); + switch (oper()) { + case RelationalOperator::equal: + case RelationalOperator::greater_or_equal: + return {ref_value}; + case RelationalOperator::greater: + return {ref_value + 1}; + case RelationalOperator::not_equal: + case RelationalOperator::matches: // superset + case RelationalOperator::doesnt_match: // not superset + case RelationalOperator::equal_icase: // subset + case RelationalOperator::not_equal_icase: // not subset + case RelationalOperator::matches_icase: // contains any + case RelationalOperator::doesnt_match_icase: // contains none of + case RelationalOperator::less: + case RelationalOperator::less_or_equal: + return {}; + } + return {}; // unreachable +} + +std::optional TimeFilter::leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + if (column_name != columnName()) { + return {}; // wrong column + } + int32_t ref_value = _ref_value - timezone_offset.count(); + switch (oper()) { + case RelationalOperator::equal: + case RelationalOperator::less_or_equal: + return {ref_value}; + case RelationalOperator::less: + return {ref_value - 1}; + case RelationalOperator::not_equal: + case RelationalOperator::matches: // superset + case RelationalOperator::doesnt_match: // not superset + case RelationalOperator::equal_icase: // subset + case RelationalOperator::not_equal_icase: // not subset + case RelationalOperator::matches_icase: // contains any + case RelationalOperator::doesnt_match_icase: // contains none of + case RelationalOperator::greater_or_equal: + case RelationalOperator::greater: + return {}; + } + return {}; // unreachable +} + +std::optional> TimeFilter::valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const { + if (column_name != columnName()) { + return {}; // wrong column + } + std::bitset<32> result; + for (int32_t bit = 0; bit < 32; ++bit) { + result[bit] = eval(bit, oper(), _ref_value - timezone_offset.count()); + } + return {result}; +} + +std::unique_ptr TimeFilter::copy() const { + return std::make_unique(*this); +} + +std::unique_ptr TimeFilter::negate() const { + return std::make_unique( + kind(), _column, negateRelationalOperator(oper()), value()); +} diff --git a/src/TimeFilter.h b/src/TimeFilter.h new file mode 100644 index 0000000..10a08e8 --- /dev/null +++ b/src/TimeFilter.h @@ -0,0 +1,70 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TimeFilter_h +#define TimeFilter_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include "ColumnFilter.h" +#include "Filter.h" +#include "contact_fwd.h" +#include "opids.h" +class Row; +class TimeColumn; + +class TimeFilter : public ColumnFilter { +public: + TimeFilter(Kind kind, const TimeColumn &column, RelationalOperator relOp, + const std::string &value); + + bool accepts(Row row, const contact *auth_user, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::optional greatestLowerBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::optional leastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::optional> valueSetLeastUpperBoundFor( + const std::string &column_name, + std::chrono::seconds timezone_offset) const override; + + [[nodiscard]] std::unique_ptr copy() const override; + [[nodiscard]] std::unique_ptr negate() const override; + +private: + const TimeColumn &_column; + const int32_t _ref_value; +}; + +#endif // TimeFilter_h diff --git a/src/TimePointerColumn.h b/src/TimePointerColumn.h new file mode 100644 index 0000000..da467d3 --- /dev/null +++ b/src/TimePointerColumn.h @@ -0,0 +1,51 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TimePointerColumn_h +#define TimePointerColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include "Column.h" +#include "TimeColumn.h" +#include "opids.h" +class Filter; +class RowRenderer; + +class TimePointerColumn : public TimeColumn { +public: + TimePointerColumn(const std::string &name, const std::string &description, + const time_t *number) + : TimeColumn(name, description, -1, -1, -1, 0), _number(number) {} + +private: + const time_t *const _number; + + [[nodiscard]] std::chrono::system_clock::time_point getRawValue( + Row /* row */) const override { + return std::chrono::system_clock::from_time_t(*_number); + } +}; + +#endif // TimePointerColumn_h diff --git a/src/TimeperiodColumn.cc b/src/TimeperiodColumn.cc new file mode 100644 index 0000000..dbad88b --- /dev/null +++ b/src/TimeperiodColumn.cc @@ -0,0 +1,55 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TimeperiodColumn.h" +#include "Row.h" + +#ifdef CMC +#include "Timeperiod.h" +#else +#include "TimeperiodsCache.h" +#include "nagios.h" +#endif + +TimeperiodColumn::TimeperiodColumn(const std::string& name, + const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset) + : IntColumn(name, description, indirect_offset, extra_offset, + extra_extra_offset, offset) {} + +int32_t TimeperiodColumn::getValue(Row row, + const contact* /* auth_user */) const { +#ifdef CMC + if (auto tp = columnData(row)) { + return tp->isActive() ? 1 : 0; + } +#else + extern TimeperiodsCache* g_timeperiods_cache; + if (auto tp = columnData(row)) { + return g_timeperiods_cache->inTimeperiod(tp) ? 1 : 0; + } +#endif + return 1; // unknown timeperiod is assumed to be 24X7 +} diff --git a/src/TimeperiodColumn.h b/src/TimeperiodColumn.h new file mode 100644 index 0000000..5f704ec --- /dev/null +++ b/src/TimeperiodColumn.h @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TimeperiodColumn_h +#define TimeperiodColumn_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include "IntColumn.h" +#include "contact_fwd.h" +class Row; + +class TimeperiodColumn : public IntColumn { +public: + TimeperiodColumn(const std::string& name, const std::string& description, + int indirect_offset, int extra_offset, + int extra_extra_offset, int offset); + int32_t getValue(Row row, const contact* auth_user) const override; +}; + +#endif // TimeperiodColumn_h diff --git a/src/TimeperiodsCache.cc b/src/TimeperiodsCache.cc new file mode 100644 index 0000000..cb68cd1 --- /dev/null +++ b/src/TimeperiodsCache.cc @@ -0,0 +1,113 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "TimeperiodsCache.h" +#include +#include +#include +#include +#include "Logger.h" + +extern timeperiod *timeperiod_list; + +TimeperiodsCache::TimeperiodsCache(Logger *logger) : _logger(logger) {} + +void TimeperiodsCache::logCurrentTimeperiods() { + std::lock_guard lg(_mutex); + // Loop over all timeperiods and compute if we are currently in. Detect the + // case where no time periods are known (yet!). This might be the case when + // a timed event broker message arrives *before* the start of the event + // loop. + auto now = + std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + for (timeperiod *tp = timeperiod_list; tp != nullptr; tp = tp->next) { + bool is_in = check_time_against_period(now, tp) == 0; + // check previous state and log transition if state has changed + auto it = _cache.find(tp); + if (it == _cache.end()) { // first entry + logTransition(tp->name, -1, is_in ? 1 : 0); + _cache.emplace(tp, is_in); + } + logTransition(tp->name, it->second ? 1 : 0, is_in ? 1 : 0); + } +} + +void TimeperiodsCache::update(std::chrono::system_clock::time_point now) { + std::lock_guard lg(_mutex); + // Update cache only once a minute. The timeperiod definitions have a + // 1-minute granularity, so a 1-second resultion is not needed. + if (now < _last_update + std::chrono::minutes(1)) { + return; + } + _last_update = now; + + // Loop over all timeperiods and compute if we are currently in. Detect the + // case where no time periods are known (yet!). This might be the case when + // a timed event broker message arrives *before* the start of the event + // loop. + for (timeperiod *tp = timeperiod_list; tp != nullptr; tp = tp->next) { + bool is_in = check_time_against_period( + std::chrono::system_clock::to_time_t(now), tp) == 0; + // check previous state and log transition if state has changed + auto it = _cache.find(tp); + if (it == _cache.end()) { // first entry + logTransition(tp->name, -1, is_in ? 1 : 0); + _cache.emplace(tp, is_in); + } else if (it->second != is_in) { + logTransition(tp->name, it->second ? 1 : 0, is_in ? 1 : 0); + it->second = is_in; + } + } + if (timeperiod_list != nullptr) { + Informational(_logger) + << "Timeperiod cache not updated, there are no timeperiods (yet)"; + } +} + +bool TimeperiodsCache::inTimeperiod(const std::string &tpname) const { + for (timeperiod *tp = timeperiod_list; tp != nullptr; tp = tp->next) { + if (tpname == tp->name) { + return inTimeperiod(tp); + } + } + return true; // unknown timeperiod is assumed to be 24X7 +} + +bool TimeperiodsCache::inTimeperiod(const timeperiod *tp) const { + std::lock_guard lg(_mutex); + auto it = _cache.find(tp); + if (it == _cache.end()) { + // Problem: check_time_against_period is not thread safe, so we can't + // use it here. + Informational(_logger) << "No timeperiod information available for " + << tp->name << ". Assuming out of period."; + return false; + } + return it->second; +} + +void TimeperiodsCache::logTransition(char *name, int from, int to) const { + Informational(_logger) << "TIMEPERIOD TRANSITION: " << name << ";" << from + << ";" << to; +} diff --git a/src/TimeperiodsCache.h b/src/TimeperiodsCache.h new file mode 100644 index 0000000..b227169 --- /dev/null +++ b/src/TimeperiodsCache.h @@ -0,0 +1,55 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef TimeperiodsCache_h +#define TimeperiodsCache_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include +#include "nagios.h" +class Logger; + +class TimeperiodsCache { +public: + explicit TimeperiodsCache(Logger *logger); + void update(std::chrono::system_clock::time_point now); + bool inTimeperiod(const timeperiod *tp) const; + bool inTimeperiod(const std::string &tpname) const; + void logCurrentTimeperiods(); + +private: + Logger *const _logger; + + // The mutex protects _last_update and _cache. + mutable std::mutex _mutex; + std::chrono::system_clock::time_point _last_update; + std::map _cache; + + void logTransition(char *name, int from, int to) const; +}; + +#endif // TimeperiodsCache_h diff --git a/src/Triggers.cc b/src/Triggers.cc new file mode 100644 index 0000000..7b0d938 --- /dev/null +++ b/src/Triggers.cc @@ -0,0 +1,83 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "Triggers.h" +#include + +Triggers::Kind Triggers::find(const std::string &name) { + if (name == "all") { + return Kind::all; + } + if (name == "check") { + return Kind::check; + } + if (name == "state") { + return Kind::state; + } + if (name == "log") { + return Kind::log; + } + if (name == "downtime") { + return Kind::downtime; + } + if (name == "comment") { + return Kind::comment; + } + if (name == "command") { + return Kind::command; + } + if (name == "program") { + return Kind::program; + } + throw std::runtime_error( + "invalid trigger '" + name + + "', allowed: all, check, state, log, downtime, comment, command and program"); +} + +void Triggers::notify_all(Kind trigger) { + condition_variable_for(Kind::all).notify_all(); + condition_variable_for(trigger).notify_all(); +} + +std::condition_variable &Triggers::condition_variable_for(Kind trigger) { + switch (trigger) { + case Kind::all: + return _cond_all; + case Kind::check: + return _cond_check; + case Kind::state: + return _cond_state; + case Kind::log: + return _cond_log; + case Kind::downtime: + return _cond_downtime; + case Kind::comment: + return _cond_comment; + case Kind::command: + return _cond_command; + case Kind::program: + return _cond_program; + } + return _cond_all; // unreachable +} diff --git a/src/Triggers.h b/src/Triggers.h new file mode 100644 index 0000000..03dcb69 --- /dev/null +++ b/src/Triggers.h @@ -0,0 +1,78 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef Triggers_h +#define Triggers_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +#include + +class Triggers { +public: + enum class Kind { + all, + check, + state, + log, + downtime, + comment, + command, + program + }; + + Kind find(const std::string &name); + + void notify_all(Kind trigger); + + template + void wait_for(Kind trigger, + const std::chrono::duration &rel_time, + Predicate pred) { + std::unique_lock ul(_mutex); + auto &cond = condition_variable_for(trigger); + if (rel_time == rel_time.zero()) { + cond.wait(ul, pred); + } else { + cond.wait_for(ul, rel_time, pred); + } + } + +private: + std::mutex _mutex; + std::condition_variable _cond_all; + std::condition_variable _cond_check; + std::condition_variable _cond_state; + std::condition_variable _cond_log; + std::condition_variable _cond_downtime; + std::condition_variable _cond_comment; + std::condition_variable _cond_command; + std::condition_variable _cond_program; + + std::condition_variable &condition_variable_for(Kind trigger); +}; + +#endif // Triggers_h diff --git a/src/auth.cc b/src/auth.cc new file mode 100644 index 0000000..4acbd06 --- /dev/null +++ b/src/auth.cc @@ -0,0 +1,118 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "auth.h" +#include "MonitoringCore.h" + +contact *unknown_auth_user() { return reinterpret_cast(0xdeadbeaf); } + +namespace { +bool host_has_contact(const host *hst, const contact *ctc) { + // Older Nagios headers are not const-correct... :-P + return is_contact_for_host(const_cast(hst), + const_cast(ctc)) != 0 || + is_escalated_contact_for_host(const_cast(hst), + const_cast(ctc)) != 0; +} + +bool service_has_contact(MonitoringCore *mc, const host *hst, + const service *svc, const contact *ctc) { + // Older Nagios headers are not const-correct... :-P + return is_contact_for_service(const_cast(svc), + const_cast(ctc)) != 0 || + is_escalated_contact_for_service(const_cast(svc), + const_cast(ctc)) != 0 || + (mc->serviceAuthorization() == AuthorizationKind::loose && + host_has_contact(hst, ctc)); +} +} // namespace + +bool is_authorized_for(MonitoringCore *mc, const contact *ctc, const host *hst, + const service *svc) { + return ctc != unknown_auth_user() && + (svc == nullptr ? host_has_contact(hst, ctc) + : service_has_contact(mc, hst, svc, ctc)); +} + +bool is_authorized_for_host_group(MonitoringCore *mc, const hostgroup *hg, + const contact *ctc) { + if (ctc == nullptr) { + return true; + } + if (ctc == unknown_auth_user()) { + return false; + } + + auto has_contact = [=](hostsmember *mem) { + return is_authorized_for(mc, ctc, mem->host_ptr, nullptr); + }; + if (mc->groupAuthorization() == AuthorizationKind::loose) { + // TODO(sp) Need an iterator here, "loose" means "any_of" + for (hostsmember *mem = hg->members; mem != nullptr; mem = mem->next) { + if (has_contact(mem)) { + return true; + } + } + return false; + } + // TODO(sp) Need an iterator here, "strict" means "all_of" + for (hostsmember *mem = hg->members; mem != nullptr; mem = mem->next) { + if (!has_contact(mem)) { + return false; + } + } + return true; +} + +bool is_authorized_for_service_group(MonitoringCore *mc, const servicegroup *sg, + const contact *ctc) { + if (ctc == nullptr) { + return true; + } + if (ctc == unknown_auth_user()) { + return false; + } + + auto has_contact = [=](servicesmember *mem) { + service *svc = mem->service_ptr; + return is_authorized_for(mc, ctc, svc->host_ptr, svc); + }; + if (mc->groupAuthorization() == AuthorizationKind::loose) { + // TODO(sp) Need an iterator here, "loose" means "any_of" + for (servicesmember *mem = sg->members; mem != nullptr; + mem = mem->next) { + if (has_contact(mem)) { + return true; + } + } + return false; + } + // TODO(sp) Need an iterator here, "strict" means "all_of" + for (servicesmember *mem = sg->members; mem != nullptr; mem = mem->next) { + if (!has_contact(mem)) { + return false; + } + } + return true; +} diff --git a/src/auth.h b/src/auth.h new file mode 100644 index 0000000..a187ff9 --- /dev/null +++ b/src/auth.h @@ -0,0 +1,53 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef auth_h +#define auth_h + +#include "config.h" // IWYU pragma: keep + +#ifdef CMC +#include "contact_fwd.h" +#else +#include "nagios.h" +#endif + +enum class AuthorizationKind { loose = 0, strict = 1 }; + +#ifdef CMC +inline contact *unknown_auth_user() { + return reinterpret_cast(0xdeadbeaf); +} +#else +contact *unknown_auth_user(); +class MonitoringCore; +bool is_authorized_for(MonitoringCore *mc, const contact *ctc, const host *hst, + const service *svc); +bool is_authorized_for_host_group(MonitoringCore *mc, const hostgroup *hg, + const contact *ctc); +bool is_authorized_for_service_group(MonitoringCore *mc, const servicegroup *sg, + const contact *ctc); +#endif + +#endif // auth_h diff --git a/src/contact_fwd.h b/src/contact_fwd.h new file mode 100644 index 0000000..a6a7869 --- /dev/null +++ b/src/contact_fwd.h @@ -0,0 +1,37 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef contact_fwd_h +#define contact_fwd_h + +#if defined(CMC) +class Contact; +using contact = Contact; +#elif defined(NAGIOS4) +typedef struct contact contact; +#else +using contact = struct contact_struct; +#endif + +#endif // contact_fwd_h diff --git a/src/data_encoding.h b/src/data_encoding.h new file mode 100644 index 0000000..acd6ca0 --- /dev/null +++ b/src/data_encoding.h @@ -0,0 +1,32 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef data_encoding_h +#define data_encoding_h + +#include "config.h" // IWYU pragma: keep + +enum class Encoding { utf8, latin1, mixed }; + +#endif // data_encoding_h diff --git a/src/global_counters.cc b/src/global_counters.cc new file mode 100644 index 0000000..79fa023 --- /dev/null +++ b/src/global_counters.cc @@ -0,0 +1,74 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "global_counters.h" +#include +#include + +namespace { +constexpr int num_counters = 11; + +struct CounterInfo { + double value; + double last_value; + double rate; +}; + +std::vector counters(num_counters); + +CounterInfo &counter(Counter which) { + return counters[static_cast(which)]; +} + +time_t last_statistics_update = 0; +constexpr time_t statistics_interval = 5; +constexpr double rating_weight = 0.25; + +double lerp(double a, double b, double t) { return (1 - t) * a + t * b; } +} // namespace + +void counterIncrement(Counter which) { counter(which).value++; } + +const double *counterAddress(Counter which) { return &counter(which).value; } + +const double *counterRateAddress(Counter which) { return &counter(which).rate; } + +void do_statistics() { + time_t now = time(nullptr); + if (last_statistics_update == 0) { + last_statistics_update = now; + return; + } + time_t delta_time = now - last_statistics_update; + if (delta_time < statistics_interval) { + return; + } + last_statistics_update = now; + for (auto &c : counters) { + double old_rate = c.rate; + double new_rate = (c.value - c.last_value) / delta_time; + c.rate = lerp(old_rate, new_rate, old_rate == 0 ? 1 : rating_weight); + c.last_value = c.value; + } +} diff --git a/src/global_counters.h b/src/global_counters.h new file mode 100644 index 0000000..a0c01f6 --- /dev/null +++ b/src/global_counters.h @@ -0,0 +1,51 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef global_counters_h +#define global_counters_h + +#include "config.h" // IWYU pragma: keep + +// Remember to update num_counters when you change the enum below. C++ really +// lacks a feature to iterate over enums easily... +enum class Counter { + neb_callbacks, + requests, + connections, + service_checks, + host_checks, + forks, + log_messages, + commands, + livechecks, + livecheck_overflows, + overflows +}; + +void counterIncrement(Counter which); +const double *counterAddress(Counter which); +const double *counterRateAddress(Counter which); +void do_statistics(); + +#endif // global_counters_h diff --git a/src/livestatus.h b/src/livestatus.h new file mode 100644 index 0000000..47dfa06 --- /dev/null +++ b/src/livestatus.h @@ -0,0 +1,30 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef livestatus_h +#define livestatus_h + +#include "config.h" // IWYU pragma: keep + +#endif // livestatus_h diff --git a/src/mk_inventory.cc b/src/mk_inventory.cc new file mode 100644 index 0000000..b82433b --- /dev/null +++ b/src/mk_inventory.cc @@ -0,0 +1,31 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "mk_inventory.h" +#include + +time_t mk_inventory_last(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) != 0 ? 0 : st.st_mtime; +} diff --git a/src/mk_inventory.h b/src/mk_inventory.h new file mode 100644 index 0000000..da162fb --- /dev/null +++ b/src/mk_inventory.h @@ -0,0 +1,34 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef mk_inventory_h +#define mk_inventory_h + +#include "config.h" // IWYU pragma: keep +#include +#include + +time_t mk_inventory_last(const std::string &path); + +#endif // mk_inventory_h diff --git a/src/mk_logwatch.cc b/src/mk_logwatch.cc new file mode 100644 index 0000000..dc23876 --- /dev/null +++ b/src/mk_logwatch.cc @@ -0,0 +1,48 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "mk_logwatch.h" +#include +#include +#include "Logger.h" +#include "pnp4nagios.h" + +void mk_logwatch_acknowledge(Logger *logger, const std::string &logwatch_path, + const std::string &host_name, + const std::string &file_name) { + if (file_name.find('/') != std::string::npos) { + Warning(logger) << "Invalid character / in mk_logfile filename '" + << file_name << "' of host '" << host_name << "'"; + return; + } + if (logwatch_path.empty()) { + return; + } + std::string path = logwatch_path + pnp_cleanup(host_name) + "/" + file_name; + if (unlink(path.c_str()) != 0) { + generic_error ge("Cannot acknowledge mk_logfile file '" + file_name + + "' of host '" + host_name + "'"); + Warning(logger) << ge; + } +} diff --git a/src/mk_logwatch.h b/src/mk_logwatch.h new file mode 100644 index 0000000..b373911 --- /dev/null +++ b/src/mk_logwatch.h @@ -0,0 +1,36 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef mk_logwatch_h +#define mk_logwatch_h + +#include "config.h" // IWYU pragma: keep +#include +class Logger; + +void mk_logwatch_acknowledge(Logger *logger, const std::string &logwatch_path, + const std::string &host_name, + const std::string &file_name); + +#endif // mk_logwatch_h diff --git a/src/module.cc b/src/module.cc new file mode 100644 index 0000000..993d3f1 --- /dev/null +++ b/src/module.cc @@ -0,0 +1,1175 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +// Needed for S_ISSOCK +#define _XOPEN_SOURCE 500 + +// https://github.com/include-what-you-use/include-what-you-use/issues/166 +// IWYU pragma: no_include +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ChronoUtils.h" +#include "ClientQueue.h" +#include "DowntimeOrComment.h" +#include "DowntimesOrComments.h" +#include "InputBuffer.h" +#include "LogEntry.h" // IWYU pragma: keep +#include "Logger.h" +#include "MonitoringCore.h" +#include "OutputBuffer.h" +#include "Poller.h" +#include "RegExp.h" +#include "Store.h" +#include "StringUtils.h" +#include "TimeperiodsCache.h" +#include "Triggers.h" +#include "auth.h" +#include "contact_fwd.h" +#include "data_encoding.h" +#include "global_counters.h" +#include "nagios.h" +#include "strutil.h" + +NEB_API_VERSION(CURRENT_NEB_API_VERSION) +#ifndef NAGIOS4 +extern int event_broker_options; +#else +extern unsigned long event_broker_options; +#endif // NAGIOS4 +extern int enable_environment_macros; +extern char *log_file; + +// maximum idle time for connection in keep alive state +static std::chrono::milliseconds fl_idle_timeout = std::chrono::minutes(5); + +// maximum time for reading a query +static std::chrono::milliseconds fl_query_timeout = std::chrono::seconds(10); + +// allow 10 concurrent connections per default +size_t g_livestatus_threads = 10; +// current number of queued connections (for statistics) +int g_num_queued_connections = 0; +// current number of active connections (for statistics) +std::atomic_int32_t g_livestatus_active_connections{0}; +size_t g_thread_stack_size = 1024 * 1024; /* stack size of threads */ + +void *g_nagios_handle; +int g_unix_socket = -1; +int g_max_fd_ever = 0; +static std::string fl_socket_path; +static char fl_pnp_path[4096]; +static char fl_mk_inventory_path[4096]; +static char fl_structured_status_path[4096]; +static char fl_mk_logwatch_path[4096]; +static std::string fl_logfile_path; +static std::string fl_mkeventd_socket_path; +static bool fl_should_terminate = false; + +struct ThreadInfo { + pthread_t id; + std::string name; +}; + +static std::vector fl_thread_info; +static thread_local ThreadInfo *tl_info; +size_t fl_max_cached_messages = 500000; +// do never read more than that number of lines from a logfile +static size_t fl_max_lines_per_logfile = 1000000; +size_t fl_max_response_size = 100 * 1024 * 1024; // limit answer to 10 MB +int g_thread_running = 0; +static AuthorizationKind fl_service_authorization = AuthorizationKind::loose; +static AuthorizationKind fl_group_authorization = AuthorizationKind::strict; +Encoding fl_data_encoding = Encoding::utf8; +Triggers fl_triggers; + +// Map to speed up access via name/alias/address +std::unordered_map fl_hosts_by_designation; + +static Logger *fl_logger_nagios = nullptr; +static Logger *fl_logger_livestatus = nullptr; +static LogLevel fl_livestatus_log_level = LogLevel::notice; +static Store *fl_store = nullptr; +static ClientQueue *fl_client_queue = nullptr; +TimeperiodsCache *g_timeperiods_cache = nullptr; + +/* simple statistics data for TableStatus */ +extern host *host_list; +extern service *service_list; +extern int log_initial_states; + +int g_num_hosts; +int g_num_services; + +constexpr const char *default_socket_path = "/usr/local/nagios/var/rw/live"; + +void count_hosts() { + g_num_hosts = 0; + for (host *h = host_list; h != nullptr; h = h->next) { + g_num_hosts++; + } +} + +void count_services() { + g_num_services = 0; + for (service *s = service_list; s != nullptr; s = s->next) { + g_num_services++; + } +} + +void *voidp; + +void livestatus_count_fork() { counterIncrement(Counter::forks); } + +void livestatus_cleanup_after_fork() { + // 4.2.2010: Deactivate the cleanup function. It might cause + // more trouble than it tries to avoid. It might lead to a deadlock + // with Nagios' fork()-mechanism... + // store_deinit(); + struct stat st; + + int i; + // We need to close our server and client sockets. Otherwise + // our connections are inherited to host and service checks. + // If we close our client connection in such a situation, + // the connection will still be open since and the client will + // hang while trying to read further data. And the CLOEXEC is + // not atomic :-( + + // Eventuell sollte man hier anstelle von store_deinit() nicht + // darauf verlassen, dass die ClientQueue alle Verbindungen zumacht. + // Es sind ja auch Dateideskriptoren offen, die von Threads gehalten + // werden und nicht mehr in der Queue sind. Und in store_deinit() + // wird mit mutexes rumgemacht.... + for (i = 3; i < g_max_fd_ever; i++) { + if (0 == fstat(i, &st) && S_ISSOCK(st.st_mode)) { + close(i); + } + } +} + +void *main_thread(void *data) { + tl_info = static_cast(data); + while (!fl_should_terminate) { + do_statistics(); + + Poller poller; + poller.addFileDescriptor(g_unix_socket, PollEvents::in); + int retval = poller.poll(std::chrono::milliseconds(2500)); + if (retval > 0 && + poller.isFileDescriptorSet(g_unix_socket, PollEvents::in)) { +#if HAVE_ACCEPT4 + int cc = accept4(g_unix_socket, nullptr, nullptr, SOCK_CLOEXEC); +#else + int cc = accept(g_unix_socket, nullptr, nullptr); +#endif + if (cc == -1) { + generic_error ge("cannot accept client connection"); + Warning(fl_logger_livestatus) << ge; + continue; + } +#if !HAVE_ACCEPT4 + if (fcntl(cc, F_SETFD, FD_CLOEXEC) == -1) { + generic_error ge( + "cannot set close-on-exec bit on client socket"); + Alert(fl_logger_livestatus) << ge; + break; + } +#endif + if (cc > g_max_fd_ever) { + g_max_fd_ever = cc; + } + fl_client_queue->addConnection(cc); // closes fd + g_num_queued_connections++; + counterIncrement(Counter::connections); + } + } + Notice(fl_logger_livestatus) << "socket thread has terminated"; + return voidp; +} + +void *client_thread(void *data) { + tl_info = static_cast(data); + while (!fl_should_terminate) { + int cc = fl_client_queue->popConnection(); + g_num_queued_connections--; + g_livestatus_active_connections++; + if (cc >= 0) { + Debug(fl_logger_livestatus) + << "accepted client connection on fd " << cc; + InputBuffer input_buffer(cc, fl_should_terminate, + fl_logger_livestatus, fl_query_timeout, + fl_idle_timeout); + bool keepalive = true; + unsigned requestnr = 0; + while (keepalive && !fl_should_terminate) { + if (++requestnr > 1) { + Debug(fl_logger_livestatus) + << "handling request " << requestnr + << " on same connection"; + } + counterIncrement(Counter::requests); + OutputBuffer output_buffer(cc, fl_should_terminate, + fl_logger_livestatus); + keepalive = + fl_store->answerRequest(input_buffer, output_buffer); + } + close(cc); + } + g_livestatus_active_connections--; + } + return voidp; +} + +namespace { +class NagiosHandler : public Handler { +public: + NagiosHandler() { setFormatter(std::make_unique()); } + +private: + class NagiosFormatter : public Formatter { + void format(std::ostream &os, const LogRecord &record) override { + os << "livestatus: " << record.getMessage(); + } + }; + + void publish(const LogRecord &record) override { + std::ostringstream os; + getFormatter()->format(os, record); + // TODO(sp) The Nagios headers are (once again) not const-correct... + write_to_all_logs(const_cast(os.str().c_str()), + NSLOG_INFO_MESSAGE); + } +}; + +class LivestatusHandler : public FileHandler { +public: + explicit LivestatusHandler(const std::string &filename) + : FileHandler(filename) { + setFormatter(std::make_unique()); + } + +private: + class LivestatusFormatter : public Formatter { + void format(std::ostream &os, const LogRecord &record) override { + os << FormattedTimePoint(record.getTimePoint()) << " [" + << tl_info->name << "] " << record.getMessage(); + } + } _formatter; +}; +} // namespace + +void start_threads() { + count_hosts(); + count_services(); + + if (g_thread_running == 0) { + fl_logger_livestatus->setLevel(fl_livestatus_log_level); + fl_logger_livestatus->setUseParentHandlers(false); + try { + fl_logger_livestatus->setHandler( + std::make_unique(fl_logfile_path)); + } catch (const generic_error &ex) { + Warning(fl_logger_nagios) << ex; + } + + Informational(fl_logger_nagios) + << "starting main thread and " << g_livestatus_threads + << " client threads"; + + pthread_atfork(livestatus_count_fork, nullptr, + livestatus_cleanup_after_fork); + + pthread_attr_t attr; + pthread_attr_init(&attr); + size_t defsize; + if (pthread_attr_getstacksize(&attr, &defsize) == 0) { + Debug(fl_logger_nagios) << "default stack size is " << defsize; + } + if (pthread_attr_setstacksize(&attr, g_thread_stack_size) != 0) { + Warning(fl_logger_nagios) + << "cannot set thread stack size to " << g_thread_stack_size; + } else { + Debug(fl_logger_nagios) + << "setting thread stack size to " << g_thread_stack_size; + } + + fl_thread_info.resize(g_livestatus_threads + 1); + for (auto &info : fl_thread_info) { + ptrdiff_t idx = &info - &fl_thread_info[0]; + if (idx == 0) { + // start thread that listens on socket + info.name = "main"; + pthread_create(&info.id, nullptr, main_thread, &info); + // Our current thread (i.e. the main one, confusing terminology) + // needs thread-local infos for logging, too. + tl_info = &info; + } else { + info.name = "client " + std::to_string(idx); + pthread_create(&info.id, &attr, client_thread, &info); + } + } + + g_thread_running = 1; + pthread_attr_destroy(&attr); + } +} + +void terminate_threads() { + if (g_thread_running != 0) { + fl_should_terminate = true; + Informational(fl_logger_nagios) << "waiting for main to terminate..."; + pthread_join(fl_thread_info[0].id, nullptr); + Informational(fl_logger_nagios) + << "waiting for client threads to terminate..."; + fl_client_queue->terminate(); + for (const auto &info : fl_thread_info) { + if (pthread_join(info.id, nullptr) != 0) { + Warning(fl_logger_nagios) + << "could not join thread " << info.name; + } + } + Informational(fl_logger_nagios) + << "main thread + " << g_livestatus_threads + << " client threads have finished"; + g_thread_running = 0; + fl_should_terminate = false; + } +} + +bool open_unix_socket() { + struct stat st; + if (stat(fl_socket_path.c_str(), &st) == 0) { + if (unlink(fl_socket_path.c_str()) == 0) { + Debug(fl_logger_nagios) + << "removed old socket file " << fl_socket_path; + } else { + generic_error ge("cannot remove old socket file " + fl_socket_path); + Alert(fl_logger_nagios) << ge; + return false; + } + } + + g_unix_socket = socket(PF_UNIX, SOCK_STREAM, 0); + g_max_fd_ever = g_unix_socket; + if (g_unix_socket < 0) { + generic_error ge("cannot create UNIX socket"); + Critical(fl_logger_nagios) << ge; + return false; + } + + // Imortant: close on exec -> check plugins must not inherit it! + if (fcntl(g_unix_socket, F_SETFD, FD_CLOEXEC) == -1) { + generic_error ge("cannot set close-on-exec bit on socket"); + Alert(fl_logger_nagios) << ge; + close(g_unix_socket); + return false; + } + + // Bind it to its address. This creates the file with the name + // fl_socket_path + struct sockaddr_un sockaddr; + sockaddr.sun_family = AF_UNIX; + strncpy(sockaddr.sun_path, fl_socket_path.c_str(), + sizeof(sockaddr.sun_path) - 1); + sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0'; + if (bind(g_unix_socket, reinterpret_cast(&sockaddr), + sizeof(sockaddr)) < 0) { + generic_error ge("cannot bind UNIX socket to address " + + fl_socket_path); + Error(fl_logger_nagios) << ge; + close(g_unix_socket); + return false; + } + + // Make writable group members (fchmod didn't do nothing for me. Don't know + // why!) + if (0 != chmod(fl_socket_path.c_str(), 0660)) { + generic_error ge("cannot change file permissions for UNIX socket at " + + fl_socket_path + " to 0660"); + Error(fl_logger_nagios) << ge; + close(g_unix_socket); + return false; + } + + if (0 != listen(g_unix_socket, 3 /* backlog */)) { + generic_error ge("cannot listen to UNIX socket at " + fl_socket_path); + Error(fl_logger_nagios) << ge; + close(g_unix_socket); + return false; + } + + Informational(fl_logger_nagios) + << "opened UNIX socket at " << fl_socket_path; + return true; +} + +void close_unix_socket() { + unlink(fl_socket_path.c_str()); + if (g_unix_socket >= 0) { + close(g_unix_socket); + g_unix_socket = -1; + } +} + +int broker_host(int event_type __attribute__((__unused__)), + void *data __attribute__((__unused__))) { + counterIncrement(Counter::neb_callbacks); + return 0; +} + +int broker_check(int event_type, void *data) { + int result = NEB_OK; + if (event_type == NEBCALLBACK_SERVICE_CHECK_DATA) { + auto c = static_cast(data); + if (c->type == NEBTYPE_SERVICECHECK_PROCESSED) { + counterIncrement(Counter::service_checks); + } + } else if (event_type == NEBCALLBACK_HOST_CHECK_DATA) { + auto c = static_cast(data); + if (c->type == NEBTYPE_HOSTCHECK_PROCESSED) { + counterIncrement(Counter::host_checks); + } + } + fl_triggers.notify_all(Triggers::Kind::check); + return result; +} + +int broker_comment(int event_type __attribute__((__unused__)), void *data) { + auto co = static_cast(data); + fl_store->registerComment(co); + counterIncrement(Counter::neb_callbacks); + fl_triggers.notify_all(Triggers::Kind::comment); + return 0; +} + +int broker_downtime(int event_type __attribute__((__unused__)), void *data) { + auto dt = static_cast(data); + fl_store->registerDowntime(dt); + counterIncrement(Counter::neb_callbacks); + fl_triggers.notify_all(Triggers::Kind::downtime); + return 0; +} + +int broker_log(int event_type __attribute__((__unused__)), + void *data __attribute__((__unused__))) { + counterIncrement(Counter::neb_callbacks); + counterIncrement(Counter::log_messages); + fl_triggers.notify_all(Triggers::Kind::log); + return 0; +} + +// called twice (start/end) for each external command, even builtin ones +int broker_command(int event_type __attribute__((__unused__)), void *data) { + auto sc = static_cast(data); + if (sc->type == NEBTYPE_EXTERNALCOMMAND_START) { + counterIncrement(Counter::commands); + if (sc->command_type == CMD_CUSTOM_COMMAND && + strcmp(sc->command_string, "_LOG") == 0) { + write_to_all_logs(sc->command_args, -1); + counterIncrement(Counter::log_messages); + fl_triggers.notify_all(Triggers::Kind::log); + } + } + counterIncrement(Counter::neb_callbacks); + fl_triggers.notify_all(Triggers::Kind::command); + return 0; +} + +int broker_state(int event_type __attribute__((__unused__)), + void *data __attribute__((__unused__))) { + counterIncrement(Counter::neb_callbacks); + fl_triggers.notify_all(Triggers::Kind::state); + return 0; +} + +int broker_program(int event_type __attribute__((__unused__)), + void *data __attribute__((__unused__))) { + counterIncrement(Counter::neb_callbacks); + fl_triggers.notify_all(Triggers::Kind::program); + return 0; +} + +void livestatus_log_initial_states() { + extern scheduled_downtime *scheduled_downtime_list; + // It's a bit unclear if we need to log downtimes of hosts *before* their + // corresponding service downtimes, so let's play safe... + for (auto dt = scheduled_downtime_list; dt != nullptr; dt = dt->next) { + if (dt->is_in_effect != 0 && dt->type == HOST_DOWNTIME) { + Informational(fl_logger_nagios) + << "HOST DOWNTIME ALERT: " << dt->host_name << ";STARTED;" + << dt->comment; + } + } + for (auto dt = scheduled_downtime_list; dt != nullptr; dt = dt->next) { + if (dt->is_in_effect != 0 && dt->type == SERVICE_DOWNTIME) { + Informational(fl_logger_nagios) + << "SERVICE DOWNTIME ALERT: " << dt->host_name << ";" + << dt->service_description << ";STARTED;" << dt->comment; + } + } + g_timeperiods_cache->logCurrentTimeperiods(); +} + +int broker_event(int event_type __attribute__((__unused__)), void *data) { + counterIncrement(Counter::neb_callbacks); + auto ts = static_cast(data); + if (ts->event_type == EVENT_LOG_ROTATION) { + if (g_thread_running == 1) { + livestatus_log_initial_states(); + } else if (log_initial_states == 1) { + // initial info during startup + Informational(fl_logger_nagios) << "logging initial states"; + } + } + g_timeperiods_cache->update(from_timeval(ts->timestamp)); + return 0; +} + +class NagiosCore : public MonitoringCore { +public: + Host *getHostByDesignation(const std::string &designation) override { + auto it = fl_hosts_by_designation.find(mk::unsafe_tolower(designation)); + return it == fl_hosts_by_designation.end() ? nullptr + : fromImpl(it->second); + } + + bool host_has_contact(const Host *host, const Contact *contact) override { + return is_authorized_for(this, toImpl(contact), toImpl(host), nullptr); + } + + ContactGroup *find_contactgroup(const std::string &name) override { + // Older Nagios headers are not const-correct... :-P + return fromImpl(::find_contactgroup(const_cast(name.c_str()))); + } + + bool is_contact_member_of_contactgroup(const ContactGroup *group, + const Contact *contact) override { + // Older Nagios headers are not const-correct... :-P + return ::is_contact_member_of_contactgroup( + const_cast(toImpl(group)), + const_cast<::contact *>(toImpl(contact))) != 0; + } + + std::chrono::system_clock::time_point last_logfile_rotation() override { + // TODO(sp) We should better listen to NEBCALLBACK_PROGRAM_STATUS_DATA + // instead of this 'extern' hack... + extern time_t last_log_rotation; + return std::chrono::system_clock::from_time_t(last_log_rotation); + } + + [[nodiscard]] Command find_command(std::string name) const override { + // Older Nagios headers are not const-correct... :-P + if (command *cmd = ::find_command(const_cast(name.c_str()))) { + return {cmd->name, cmd->command_line}; + } + return {"", ""}; + } + + [[nodiscard]] size_t maxLinesPerLogFile() const override { + return fl_max_lines_per_logfile; + } + + [[nodiscard]] std::vector commands() const override { + extern command *command_list; + std::vector commands; + for (command *cmd = command_list; cmd != nullptr; cmd = cmd->next) { + commands.push_back({cmd->name, cmd->command_line}); + } + return commands; + } + + std::vector downtimes_for_host( + const Host *host) const override { + return downtimes_for_object(toImpl(host), nullptr); + } + + std::vector downtimes_for_service( + const Service *service) const override { + return downtimes_for_object(toImpl(service)->host_ptr, toImpl(service)); + } + + std::vector comments_for_host( + const Host *host) const override { + return comments_for_object(toImpl(host), nullptr); + } + + std::vector comments_for_service( + const Service *service) const override { + return comments_for_object(toImpl(service)->host_ptr, toImpl(service)); + } + + bool mkeventdEnabled() override { + if (const char *config_mkeventd = getenv("CONFIG_MKEVENTD")) { + return config_mkeventd == std::string("on"); + } + return false; + } + + std::string mkeventdSocketPath() override { + return fl_mkeventd_socket_path; + } + std::string mkLogwatchPath() override { return fl_mk_logwatch_path; } + std::string mkInventoryPath() override { return fl_mk_inventory_path; } + std::string structuredStatusPath() override { + return fl_structured_status_path; + } + std::string pnpPath() override { return fl_pnp_path; } + std::string historyFilePath() override { return log_file; } + std::string logArchivePath() override { + extern char *log_archive_path; + return log_archive_path; + } + Encoding dataEncoding() override { return fl_data_encoding; } + size_t maxResponseSize() override { return fl_max_response_size; } + size_t maxCachedMessages() override { return fl_max_cached_messages; } + + // TODO(sp) Unused in Livestatus NEB: Strange & ugly... + [[nodiscard]] AuthorizationKind hostAuthorization() const override { + return AuthorizationKind::loose; + } + + [[nodiscard]] AuthorizationKind serviceAuthorization() const override { + return fl_service_authorization; + } + + [[nodiscard]] AuthorizationKind groupAuthorization() const override { + return fl_group_authorization; + } + + Logger *loggerLivestatus() override { return fl_logger_livestatus; } + + Triggers &triggers() override { return fl_triggers; } + + size_t numQueuedNotifications() override { return 0; } + size_t numQueuedAlerts() override { return 0; } + +private: + [[nodiscard]] void *implInternal() const override { return fl_store; } + + static const contact *toImpl(const Contact *c) { + return reinterpret_cast(c); + } + + static const contactgroup *toImpl(const ContactGroup *g) { + return reinterpret_cast(g); + } + + static ContactGroup *fromImpl(contactgroup *g) { + return reinterpret_cast(g); + } + + static const host *toImpl(const Host *h) { + return reinterpret_cast(h); + } + static Host *fromImpl(host *h) { return reinterpret_cast(h); } + + static const service *toImpl(const Service *h) { + return reinterpret_cast(h); + } + + std::vector downtimes_for_object(const ::host *h, + const ::service *s) const { + std::vector result; + for (const auto &entry : fl_store->_downtimes) { + auto *dt = static_cast(entry.second.get()); + if (dt->_host == h && dt->_service == s) { + result.push_back({dt->_id, dt->_author_name, dt->_comment}); + } + } + return result; + } + + std::vector comments_for_object(const ::host *h, + const ::service *s) const { + std::vector result; + for (const auto &entry : fl_store->_comments) { + auto *co = static_cast(entry.second.get()); + if (co->_host == h && co->_service == s) { + result.push_back( + {co->_id, co->_author_name, co->_comment, + static_cast(co->_entry_type), + std::chrono::system_clock::from_time_t(co->_entry_time)}); + } + } + return result; + } +}; + +NagiosCore core; + +int broker_process(int event_type __attribute__((__unused__)), void *data) { + auto ps = static_cast(data); + switch (ps->type) { + case NEBTYPE_PROCESS_START: + for (host *hst = host_list; hst != nullptr; hst = hst->next) { + if (const char *address = hst->address) { + fl_hosts_by_designation[mk::unsafe_tolower(address)] = hst; + } + if (const char *alias = hst->alias) { + fl_hosts_by_designation[mk::unsafe_tolower(alias)] = hst; + } + fl_hosts_by_designation[mk::unsafe_tolower(hst->name)] = hst; + } + fl_store = new Store(&core); + fl_client_queue = new ClientQueue(); + g_timeperiods_cache = new TimeperiodsCache(fl_logger_nagios); + break; + case NEBTYPE_PROCESS_EVENTLOOPSTART: + g_timeperiods_cache->update(from_timeval(ps->timestamp)); + start_threads(); + break; + default: + break; + } + return 0; +} + +int verify_event_broker_options() { + int errors = 0; + if ((event_broker_options & BROKER_PROGRAM_STATE) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_PROGRAM_STATE (" << BROKER_PROGRAM_STATE + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_TIMED_EVENTS) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_TIMED_EVENTS (" << BROKER_TIMED_EVENTS + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_SERVICE_CHECKS) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_SERVICE_CHECKS (" << BROKER_SERVICE_CHECKS + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_HOST_CHECKS) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_HOST_CHECKS (" << BROKER_HOST_CHECKS + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_LOGGED_DATA) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_LOGGED_DATA (" << BROKER_LOGGED_DATA + << ") event_broker_option enabled to work.", + errors++; + } + if ((event_broker_options & BROKER_COMMENT_DATA) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_COMMENT_DATA (" << BROKER_COMMENT_DATA + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_DOWNTIME_DATA) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_DOWNTIME_DATA (" << BROKER_DOWNTIME_DATA + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_STATUS_DATA) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_STATUS_DATA (" << BROKER_STATUS_DATA + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_ADAPTIVE_DATA) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_ADAPTIVE_DATA (" << BROKER_ADAPTIVE_DATA + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_EXTERNALCOMMAND_DATA) == 0) { + Critical(fl_logger_nagios) << "need BROKER_EXTERNALCOMMAND_DATA (" + << BROKER_EXTERNALCOMMAND_DATA + << ") event_broker_option enabled to work."; + errors++; + } + if ((event_broker_options & BROKER_STATECHANGE_DATA) == 0) { + Critical(fl_logger_nagios) + << "need BROKER_STATECHANGE_DATA (" << BROKER_STATECHANGE_DATA + << ") event_broker_option enabled to work."; + errors++; + } + + return static_cast(errors == 0); +} + +void register_callbacks() { + neb_register_callback(NEBCALLBACK_HOST_STATUS_DATA, g_nagios_handle, 0, + broker_host); // Needed to start threads + neb_register_callback(NEBCALLBACK_COMMENT_DATA, g_nagios_handle, 0, + broker_comment); // dynamic data + neb_register_callback(NEBCALLBACK_DOWNTIME_DATA, g_nagios_handle, 0, + broker_downtime); // dynamic data + neb_register_callback(NEBCALLBACK_SERVICE_CHECK_DATA, g_nagios_handle, 0, + broker_check); // only for statistics + neb_register_callback(NEBCALLBACK_HOST_CHECK_DATA, g_nagios_handle, 0, + broker_check); // only for statistics + neb_register_callback(NEBCALLBACK_LOG_DATA, g_nagios_handle, 0, + broker_log); // only for trigger 'log' + neb_register_callback(NEBCALLBACK_EXTERNAL_COMMAND_DATA, g_nagios_handle, 0, + broker_command); // only for trigger 'command' + neb_register_callback(NEBCALLBACK_STATE_CHANGE_DATA, g_nagios_handle, 0, + broker_state); // only for trigger 'state' + neb_register_callback(NEBCALLBACK_ADAPTIVE_PROGRAM_DATA, g_nagios_handle, 0, + broker_program); // only for trigger 'program' + neb_register_callback(NEBCALLBACK_PROCESS_DATA, g_nagios_handle, 0, + broker_process); // used for starting threads + neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, g_nagios_handle, 0, + broker_event); // used for timeperiods cache +} + +void deregister_callbacks() { + neb_deregister_callback(NEBCALLBACK_HOST_STATUS_DATA, broker_host); + neb_deregister_callback(NEBCALLBACK_COMMENT_DATA, broker_comment); + neb_deregister_callback(NEBCALLBACK_DOWNTIME_DATA, broker_downtime); + neb_deregister_callback(NEBCALLBACK_SERVICE_CHECK_DATA, broker_check); + neb_deregister_callback(NEBCALLBACK_HOST_CHECK_DATA, broker_check); + neb_deregister_callback(NEBCALLBACK_LOG_DATA, broker_log); + neb_deregister_callback(NEBCALLBACK_EXTERNAL_COMMAND_DATA, broker_command); + neb_deregister_callback(NEBCALLBACK_STATE_CHANGE_DATA, broker_state); + neb_deregister_callback(NEBCALLBACK_ADAPTIVE_PROGRAM_DATA, broker_program); + neb_deregister_callback(NEBCALLBACK_PROCESS_DATA, broker_program); + neb_deregister_callback(NEBCALLBACK_TIMED_EVENT_DATA, broker_event); +} + +void check_path(const char *name, char *path) { + struct stat st; + if (0 == stat(path, &st)) { + if (0 != access(path, R_OK)) { + Error(fl_logger_nagios) + << name << " '" << path + << "' not readable, please fix permissions."; + path[0] = 0; // disable + } + } else { + Error(fl_logger_nagios) << name << " '" << path << "' not existing!"; + path[0] = 0; // disable + } +} + +void livestatus_parse_arguments(const char *args_orig) { + fl_socket_path = default_socket_path; + + { + // set default path to our logfile to be in the same path as nagios.log + std::string lf{log_file}; + auto slash = lf.rfind('/'); + fl_logfile_path = + (slash == std::string::npos ? "/tmp/" : lf.substr(0, slash + 1)) + + "livestatus.log"; + } + + fl_mkeventd_socket_path = ""; + + /* there is no default PNP path */ + fl_pnp_path[0] = 0; + + if (args_orig == nullptr) { + return; // no arguments, use default options + } + + // TODO(sp) Nuke next_field and friends. Use C++ strings everywhere. + std::vector args_buf(args_orig, args_orig + strlen(args_orig) + 1); + char *args = &args_buf[0]; + while (char *token = next_field(&args)) { + /* find = */ + char *part = token; + char *left = next_token(&part, '='); + char *right = next_token(&part, 0); + if (right == nullptr) { + fl_socket_path = left; + } else { + if (strcmp(left, "debug") == 0) { + int debug_level = atoi(right); + if (debug_level >= 2) { + fl_livestatus_log_level = LogLevel::debug; + } else if (debug_level >= 1) { + fl_livestatus_log_level = LogLevel::informational; + } else { + fl_livestatus_log_level = LogLevel::notice; + } + Notice(fl_logger_nagios) + << "setting debug level to " << fl_livestatus_log_level; + } else if (strcmp(left, "log_file") == 0) { + fl_logfile_path = right; + } else if (strcmp(left, "mkeventd_socket_path") == 0) { + fl_mkeventd_socket_path = right; + } else if (strcmp(left, "max_cached_messages") == 0) { + fl_max_cached_messages = strtoul(right, nullptr, 10); + Notice(fl_logger_nagios) + << "setting max number of cached log messages to " + << fl_max_cached_messages; + } else if (strcmp(left, "max_lines_per_logfile") == 0) { + fl_max_lines_per_logfile = strtoul(right, nullptr, 10); + Notice(fl_logger_nagios) + << "setting max number lines per logfile to " + << fl_max_lines_per_logfile; + } else if (strcmp(left, "thread_stack_size") == 0) { + g_thread_stack_size = strtoul(right, nullptr, 10); + Notice(fl_logger_nagios) << "setting size of thread stacks to " + << g_thread_stack_size; + } else if (strcmp(left, "max_response_size") == 0) { + fl_max_response_size = strtoul(right, nullptr, 10); + Notice(fl_logger_nagios) + << "setting maximum response size to " + << fl_max_response_size << " bytes (" + << (fl_max_response_size / (1024.0 * 1024.0)) << " MB)"; + } else if (strcmp(left, "num_client_threads") == 0) { + int c = atoi(right); + if (c <= 0 || c > 1000) { + Warning(fl_logger_nagios) + << "cannot set num_client_threads to " << c + << ", must be > 0 and <= 1000"; + } else { + Notice(fl_logger_nagios) + << "setting number of client threads to " << c; + g_livestatus_threads = c; + } + } else if (strcmp(left, "query_timeout") == 0) { + int c = atoi(right); + if (c < 0) { + Warning(fl_logger_nagios) << "query_timeout must be >= 0"; + } else { + fl_query_timeout = std::chrono::milliseconds(c); + if (c == 0) { + Notice(fl_logger_nagios) << "disabled query timeout!"; + } else { + Notice(fl_logger_nagios) + << "Setting timeout for reading a query to " << c + << " ms"; + } + } + } else if (strcmp(left, "idle_timeout") == 0) { + int c = atoi(right); + if (c < 0) { + Warning(fl_logger_nagios) << "idle_timeout must be >= 0"; + } else { + fl_idle_timeout = std::chrono::milliseconds(c); + if (c == 0) { + Notice(fl_logger_nagios) << "disabled idle timeout!"; + } else { + Notice(fl_logger_nagios) + << "setting idle timeout to " << c << " ms"; + } + } + } else if (strcmp(left, "service_authorization") == 0) { + if (strcmp(right, "strict") == 0) { + fl_service_authorization = AuthorizationKind::strict; + } else if (strcmp(right, "loose") == 0) { + fl_service_authorization = AuthorizationKind::loose; + } else { + Warning(fl_logger_nagios) + << "invalid service authorization mode, " + "allowed are strict and loose"; + } + } else if (strcmp(left, "group_authorization") == 0) { + if (strcmp(right, "strict") == 0) { + fl_group_authorization = AuthorizationKind::strict; + } else if (strcmp(right, "loose") == 0) { + fl_group_authorization = AuthorizationKind::loose; + } else { + Warning(fl_logger_nagios) + << "invalid group authorization mode, " + "allowed are strict and loose"; + } + } else if (strcmp(left, "pnp_path") == 0) { + strncpy(fl_pnp_path, right, sizeof(fl_pnp_path) - 1); + // make sure, that trailing slash is always there + if (right[strlen(right) - 1] != '/') { + strncat(fl_pnp_path, "/", + sizeof(fl_pnp_path) - strlen(fl_pnp_path) - 1); + } + check_path("PNP perfdata directory", fl_pnp_path); + } else if (strcmp(left, "mk_inventory_path") == 0) { + strncpy(fl_mk_inventory_path, right, + sizeof(fl_mk_inventory_path) - 1); + if (right[strlen(right) - 1] != '/') { + strncat(fl_mk_inventory_path, "/", + sizeof(fl_mk_inventory_path) - + strlen(fl_mk_inventory_path) - + 1); // make sure, that trailing slash is there + } + check_path("Check_MK Inventory directory", + fl_mk_inventory_path); + } else if (strcmp(left, "structured_status_path") == 0) { + strncpy(fl_structured_status_path, right, + sizeof(fl_structured_status_path) - 1); + if (right[strlen(right) - 1] != '/') { + strncat(fl_structured_status_path, "/", + sizeof(fl_structured_status_path) - + strlen(fl_structured_status_path) - + 1); // make sure, that trailing slash is there + } + check_path("Check_MK structured status directory", + fl_structured_status_path); + } else if (strcmp(left, "mk_logwatch_path") == 0) { + strncpy(fl_mk_logwatch_path, right, + sizeof(fl_mk_logwatch_path) - 1); + if (right[strlen(right) - 1] != '/') { + strncat(fl_mk_logwatch_path, "/", + sizeof(fl_mk_logwatch_path) - + strlen(fl_mk_logwatch_path) - + 1); // make sure, that trailing slash is there + } + check_path("Check_MK logwatch directory", fl_mk_logwatch_path); + } else if (strcmp(left, "data_encoding") == 0) { + if (strcmp(right, "utf8") == 0) { + fl_data_encoding = Encoding::utf8; + } else if (strcmp(right, "latin1") == 0) { + fl_data_encoding = Encoding::latin1; + } else if (strcmp(right, "mixed") == 0) { + fl_data_encoding = Encoding::mixed; + } else { + Warning(fl_logger_nagios) + << "invalid data_encoding " << right + << ", allowed are utf8, latin1 and mixed"; + } + } else if (strcmp(left, "livecheck") == 0) { + Warning(fl_logger_nagios) + << "livecheck has been removed from Livestatus, sorry."; + } else if (strcmp(left, "disable_statehist_filtering") == 0) { + Warning(fl_logger_nagios) + << "the disable_statehist_filtering option has been removed, filtering is always active now."; + } else { + Warning(fl_logger_nagios) + << "ignoring invalid option " << left << "=" << right; + } + } + } + + if (fl_mkeventd_socket_path.empty()) { + std::string sp{fl_socket_path}; + auto slash = sp.rfind('/'); + fl_mkeventd_socket_path = + (slash == std::string::npos ? "" : sp.substr(0, slash + 1)) + + "mkeventd/status"; + } + Warning(fl_logger_nagios) + << "fl_socket_path=[" << fl_socket_path + << "], fl_mkeventd_socket_path=[" << fl_mkeventd_socket_path << "]"; +} + +void omd_advertize() { + Notice(fl_logger_nagios) + << "Livestatus by Mathias Kettner started with PID " << getpid(); + Notice(fl_logger_nagios) << "version " << VERSION << " compiled " + << BUILD_DATE << " on " << BUILD_HOSTNAME; + Notice(fl_logger_nagios) << "built with " << BUILD_CXX << ", using " + << RegExp::engine() << " regex engine"; + Notice(fl_logger_nagios) << "Using socket at '" << fl_socket_path << "'"; + Notice(fl_logger_nagios) << "Please visit us at http://mathias-kettner.de/"; + if (char *omd_site = getenv("OMD_SITE")) { + Informational(fl_logger_nagios) + << "running on OMD site " << omd_site << ", cool."; + } else { + Notice(fl_logger_nagios) + << "Hint: Please try out OMD - the Open Monitoring Distribution"; + Notice(fl_logger_nagios) << "Please visit OMD at http://omdistro.org"; + } +} + +// Called from Nagios after we have been loaded. +extern "C" int nebmodule_init(int flags __attribute__((__unused__)), char *args, + void *handle) { + fl_logger_nagios = Logger::getLogger("nagios"); + fl_logger_nagios->setHandler(std::make_unique()); + fl_logger_nagios->setUseParentHandlers(false); + + fl_logger_livestatus = Logger::getLogger("cmk.livestatus"); + + g_nagios_handle = handle; + livestatus_parse_arguments(args); + omd_advertize(); + + if (!open_unix_socket()) { + return 1; + } + + if (verify_event_broker_options() == 0) { + Critical(fl_logger_nagios) + << "bailing out, please fix event_broker_options."; + Critical(fl_logger_nagios) + << "hint: your event_broker_options are set to " + << event_broker_options << ", try setting it to -1."; + return 1; + } + Informational(fl_logger_nagios) + << "your event_broker_options are sufficient for livestatus.."; + + if (enable_environment_macros == 1) { + Notice(fl_logger_nagios) + << "environment_macros are enabled, this might decrease the " + "overall nagios performance"; + } + + register_callbacks(); + + /* Unfortunately, we cannot start our socket thread right now. + Nagios demonizes *after* having loaded the NEB modules. When + demonizing we are losing our thread. Therefore, we create the + thread the first time one of our callbacks is called. Before + that happens, we haven't got any data anyway... */ + + Notice(fl_logger_nagios) + << "finished initialization, further log messages go to " + << fl_logfile_path; + return 0; +} + +// Called from Nagios after before we are unloaded. +extern "C" int nebmodule_deinit(int flags __attribute__((__unused__)), + int reason __attribute__((__unused__))) { + Notice(fl_logger_nagios) << "deinitializing"; + terminate_threads(); + close_unix_socket(); + delete fl_store; + fl_store = nullptr; + delete fl_client_queue; + fl_client_queue = nullptr; + delete g_timeperiods_cache; + g_timeperiods_cache = nullptr; + deregister_callbacks(); + return 0; +} diff --git a/src/nagios.h b/src/nagios.h new file mode 100644 index 0000000..9a20932 --- /dev/null +++ b/src/nagios.h @@ -0,0 +1,61 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef nagios_h +#define nagios_h + +#include "config.h" // IWYU pragma: keep + +// IWYU pragma: begin_exports +#ifdef CMC +#include "cmc.h" +#else +#define NSCORE +#ifdef NAGIOS4 +#include "nagios4/broker.h" +#include "nagios4/common.h" +#include "nagios4/downtime.h" +#include "nagios4/logging.h" +#include "nagios4/macros.h" +#include "nagios4/nagios.h" +#include "nagios4/nebcallbacks.h" +#include "nagios4/neberrors.h" +#include "nagios4/nebmodules.h" +#include "nagios4/nebstructs.h" +#include "nagios4/objects.h" +#else +#include "nagios/broker.h" +#include "nagios/common.h" +#include "nagios/downtime.h" +#include "nagios/macros.h" +#include "nagios/nagios.h" +#include "nagios/nebcallbacks.h" +#include "nagios/neberrors.h" +#include "nagios/nebmodules.h" +#include "nagios/nebstructs.h" +#include "nagios/objects.h" +#endif // NAGIOS4 +#endif // CMC +// IWYU pragma: end_exports +#endif // nagios_h diff --git a/src/opids.cc b/src/opids.cc new file mode 100644 index 0000000..2654f60 --- /dev/null +++ b/src/opids.cc @@ -0,0 +1,132 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "opids.h" +#include +#include +#include +#include "RegExp.h" + +namespace { +std::unordered_map fromString = { + {"=", RelationalOperator::equal}, + {"!=", RelationalOperator::not_equal}, + {"~", RelationalOperator::matches}, + {"!~", RelationalOperator::doesnt_match}, + {"=~", RelationalOperator::equal_icase}, + {"!=~", RelationalOperator::not_equal_icase}, + {"~~", RelationalOperator::matches_icase}, + {"!~~", RelationalOperator::doesnt_match_icase}, + {"<", RelationalOperator::less}, + {"!<", RelationalOperator::greater_or_equal}, + {">=", RelationalOperator::greater_or_equal}, + {"!>=", RelationalOperator::less}, + {">", RelationalOperator::greater}, + {"!>", RelationalOperator::less_or_equal}, + {"<=", RelationalOperator::less_or_equal}, + {"!<=", RelationalOperator::greater}}; +} // namespace + +std::ostream &operator<<(std::ostream &os, const RelationalOperator &relOp) { + // Slightly inefficient, but this doesn't matter for our purposes. We could + // use Boost.Bimap or use 2 maps if really necessary. + for (const auto &strAndOp : fromString) { + if (strAndOp.second == relOp) { + return os << strAndOp.first; + } + } + return os; +} + +RelationalOperator relationalOperatorForName(const std::string &name) { + auto it = fromString.find(name); + if (it == fromString.end()) { + throw std::runtime_error("invalid operator '" + name + "'"); + } + return it->second; +} + +RelationalOperator negateRelationalOperator(RelationalOperator relOp) { + switch (relOp) { + case RelationalOperator::equal: + return RelationalOperator::not_equal; + case RelationalOperator::not_equal: + return RelationalOperator::equal; + case RelationalOperator::matches: + return RelationalOperator::doesnt_match; + case RelationalOperator::doesnt_match: + return RelationalOperator::matches; + case RelationalOperator::equal_icase: + return RelationalOperator::not_equal_icase; + case RelationalOperator::not_equal_icase: + return RelationalOperator::equal_icase; + case RelationalOperator::matches_icase: + return RelationalOperator::doesnt_match_icase; + case RelationalOperator::doesnt_match_icase: + return RelationalOperator::matches_icase; + case RelationalOperator::less: + return RelationalOperator::greater_or_equal; + case RelationalOperator::greater_or_equal: + return RelationalOperator::less; + case RelationalOperator::greater: + return RelationalOperator::less_or_equal; + case RelationalOperator::less_or_equal: + return RelationalOperator::greater; + } + return RelationalOperator::equal; // unreachable +} + +std::unique_ptr makeRegExpFor(RelationalOperator relOp, + const std::string &value) { + switch (relOp) { + case RelationalOperator::matches: + case RelationalOperator::doesnt_match: + case RelationalOperator::matches_icase: + case RelationalOperator::doesnt_match_icase: + return std::make_unique( + value, + (relOp == RelationalOperator::matches_icase || + relOp == RelationalOperator::doesnt_match_icase) + ? RegExp::Case::ignore + : RegExp::Case::respect, + RegExp::Syntax::pattern); + case RelationalOperator::equal: + case RelationalOperator::not_equal: + case RelationalOperator::equal_icase: + case RelationalOperator::not_equal_icase: + return std::make_unique( + value, + (relOp == RelationalOperator::equal_icase || + relOp == RelationalOperator::not_equal_icase) + ? RegExp::Case::ignore + : RegExp::Case::respect, + RegExp::Syntax::literal); + case RelationalOperator::less: + case RelationalOperator::greater_or_equal: + case RelationalOperator::greater: + case RelationalOperator::less_or_equal: + return nullptr; + } + return nullptr; // make the compiler happy... +} diff --git a/src/opids.h b/src/opids.h new file mode 100644 index 0000000..bf81d05 --- /dev/null +++ b/src/opids.h @@ -0,0 +1,57 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef opids_h +#define opids_h + +#include "config.h" // IWYU pragma: keep +#include +#include +#include +class RegExp; + +enum class RelationalOperator { + equal, + not_equal, + matches, + doesnt_match, + equal_icase, + not_equal_icase, + matches_icase, + doesnt_match_icase, + less, + greater_or_equal, + greater, + less_or_equal +}; + +std::ostream &operator<<(std::ostream &os, const RelationalOperator &relOp); + +RelationalOperator relationalOperatorForName(const std::string &name); + +RelationalOperator negateRelationalOperator(RelationalOperator relOp); + +std::unique_ptr makeRegExpFor(RelationalOperator relOp, + const std::string &value); +#endif // opids_h diff --git a/src/pnp4nagios.cc b/src/pnp4nagios.cc new file mode 100644 index 0000000..fac6c24 --- /dev/null +++ b/src/pnp4nagios.cc @@ -0,0 +1,66 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "pnp4nagios.h" +#include + +#ifndef CMC +#include +#include "FileSystem.h" +#include "MonitoringCore.h" +#endif + +namespace { + +// TODO(sp): Move this to some kind of C++ string utility file. +std::string replace_all(const std::string& str, const std::string& chars, + char replacement) { + std::string result(str); + size_t i = 0; + while ((i = result.find_first_of(chars, i)) != std::string::npos) { + result[i++] = replacement; + } + return result; +} +} // namespace + +std::string pnp_cleanup(const std::string& name) { + return replace_all(name, R"( /\:)", '_'); +} + +#ifndef CMC +// TODO(sp) Merge this with Perfdatabase::getPNPXMLPath +int pnpgraph_present(MonitoringCore* mc, const std::string& host, + const std::string& service) { + fs::path pnp_path = mc->pnpPath(); + if (pnp_path.empty()) { + return -1; + } + fs::path path = + pnp_path / pnp_cleanup(host) / (pnp_cleanup(service) + ".xml"); + std::error_code ec; + fs::status(path, ec); + return ec ? 0 : 1; +} +#endif diff --git a/src/pnp4nagios.h b/src/pnp4nagios.h new file mode 100644 index 0000000..3800d76 --- /dev/null +++ b/src/pnp4nagios.h @@ -0,0 +1,43 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef pnp4nagios_h +#define pnp4nagios_h + +#include "config.h" // IWYU pragma: keep +#include +#ifndef CMC +class MonitoringCore; +#endif + +inline std::string dummy_service_description() { return "_HOST_"; } + +std::string pnp_cleanup(const std::string& name); + +#ifndef CMC +int pnpgraph_present(MonitoringCore* mc, const std::string& host, + const std::string& service); +#endif + +#endif // pnp4nagios_h diff --git a/src/strutil.cc b/src/strutil.cc new file mode 100644 index 0000000..3659479 --- /dev/null +++ b/src/strutil.cc @@ -0,0 +1,85 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include "strutil.h" +#include + +// *c points to a string containing white space separated columns. This method +// returns a pointer to the zero-terminated next field. That might be identical +// with *c itself. The pointer c is then moved to the possible beginning of the +// next field. +char *next_field(char **c) { + // skip leading spaces + char *begin = *c; + while (isspace(*begin) != 0) { + begin++; + } + if (*begin == 0) { + *c = begin; + return nullptr; // found end of string -> no more field + } + + char *end = begin; // copy pointer, search end of field + while (*end != 0 && isspace(*end) == 0) { + end++; // search for \0 or white space + } + if (*end != 0) { // string continues -> terminate field with '\0' + *end = '\0'; + *c = end + 1; // skip to character right *after* '\0' + } else { + *c = end; // no more field, point to '\0' + } + return begin; +} + +/* similar to next_field() but takes one character as delimiter */ +char *next_token(char **c, char delim) { + char *begin = *c; + if (*begin == 0) { + *c = begin; + return nullptr; + } + + char *end = begin; + while (*end != 0 && *end != delim) { + end++; + } + if (*end != 0) { + *end = 0; + *c = end + 1; + } else { + *c = end; + } + return begin; +} + +/* same as next_token() but returns "" instead of 0 if + no tokens has been found */ +const char *safe_next_token(char **c, char delim) { + if (*c == nullptr) { + return ""; + } + char *result = next_token(c, delim); + return result != nullptr ? result : ""; +} diff --git a/src/strutil.h b/src/strutil.h new file mode 100644 index 0000000..4802315 --- /dev/null +++ b/src/strutil.h @@ -0,0 +1,34 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#ifndef strutil_h +#define strutil_h + +#include "config.h" // IWYU pragma: keep + +char *next_token(char **c, char delim); +const char *safe_next_token(char **c, char delim); +char *next_field(char **c); + +#endif // strutil_h diff --git a/src/unixcat.cc b/src/unixcat.cc new file mode 100644 index 0000000..714fa4c --- /dev/null +++ b/src/unixcat.cc @@ -0,0 +1,163 @@ +// +------------------------------------------------------------------+ +// | ____ _ _ __ __ _ __ | +// | / ___| |__ ___ ___| | __ | \/ | |/ / | +// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | +// | | |___| | | | __/ (__| < | | | | . \ | +// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | +// | | +// | Copyright Mathias Kettner 2014 mk@mathias-kettner.de | +// +------------------------------------------------------------------+ +// +// This file is part of Check_MK. +// The official homepage is at http://mathias-kettner.de/check_mk. +// +// check_mk 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 in version 2. check_mk is distributed +// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- +// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU General Public License for more de- +// tails. You should have received a copy of the GNU General Public +// License along with GNU Make; see the file COPYING. If not, write +// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +// Boston, MA 02110-1301 USA. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Poller.h" + +int copy_data(int from, int to); +void *voidp; + +struct thread_info { + int from; + int to; + int should_shutdown; + int terminate_on_read_eof; +}; + +void printErrno(const std::string &msg) { + std::cerr << msg + ": " + strerror(errno) << std::endl; +} + +ssize_t read_with_timeout(int from, char *buffer, int size, + std::chrono::microseconds timeout) { + Poller poller; + poller.addFileDescriptor(from, PollEvents::in); + return poller.poll(timeout) > 0 ? read(from, buffer, size) : -2; +} + +void *copy_thread(void *info) { + // https://llvm.org/bugs/show_bug.cgi?id=29089 + signal(SIGWINCH, SIG_IGN); // NOLINT + + auto *ti = static_cast(info); + int from = ti->from; + int to = ti->to; + + char read_buffer[65536]; + while (true) { + ssize_t r = read_with_timeout(from, read_buffer, sizeof(read_buffer), + std::chrono::microseconds(1000000)); + if (r == -1) { + printErrno("Error reading from " + std::to_string(from)); + break; + } + if (r == 0) { + if (ti->should_shutdown != 0) { + shutdown(to, SHUT_WR); + } + if (ti->terminate_on_read_eof != 0) { + exit(0); + return voidp; + } + break; + } + if (r == -2) { + r = 0; + } + + const char *buffer = read_buffer; + size_t bytes_to_write = r; + while (bytes_to_write > 0) { + ssize_t bytes_written = write(to, buffer, bytes_to_write); + if (bytes_written == -1) { + printErrno("Error: Cannot write " + + std::to_string(bytes_to_write) + " bytes to " + + std::to_string(to)); + break; + } + buffer += bytes_written; + bytes_to_write -= bytes_written; + } + } + return voidp; +} + +int main(int argc, char **argv) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " UNIX-socket" << std::endl; + exit(1); + } + + // https://llvm.org/bugs/show_bug.cgi?id=29089 + signal(SIGWINCH, SIG_IGN); // NOLINT + + std::string unixpath = argv[1]; + struct stat st; + + if (0 != stat(unixpath.c_str(), &st)) { + std::cerr << "No UNIX socket " << unixpath << " existing" << std::endl; + exit(2); + } + + int sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + printErrno("Cannot create client socket"); + exit(3); + } + + /* Connect */ + struct sockaddr_un sockaddr; + sockaddr.sun_family = AF_UNIX; + strncpy(sockaddr.sun_path, unixpath.c_str(), sizeof(sockaddr.sun_path) - 1); + sockaddr.sun_path[sizeof(sockaddr.sun_path) - 1] = '\0'; + if (connect(sock, reinterpret_cast(&sockaddr), + sizeof(sockaddr)) != 0) { + printErrno("Couldn't connect to UNIX-socket at " + unixpath); + close(sock); + exit(4); + } + + thread_info toleft_info = {sock, 1, 0, 1}; + thread_info toright_info = {0, sock, 1, 0}; + pthread_t toright_thread, toleft_thread; + if (pthread_create(&toright_thread, nullptr, copy_thread, &toright_info) != + 0 || + pthread_create(&toleft_thread, nullptr, copy_thread, &toleft_info) != + 0) { + printErrno("Couldn't create threads"); + close(sock); + exit(5); + } + if (pthread_join(toleft_thread, nullptr) != 0 || + pthread_join(toright_thread, nullptr) != 0) { + printErrno("Couldn't join threads"); + close(sock); + exit(6); + } + + close(sock); + return 0; +} diff --git a/standalone/config_files.m4 b/standalone/config_files.m4 new file mode 100644 index 0000000..443ac17 --- /dev/null +++ b/standalone/config_files.m4 @@ -0,0 +1,2 @@ +AC_CONFIG_FILES([Makefile + src/Makefile])