From 69e42aac8da3ecf7fd56fe627570f9d9e552c009 Mon Sep 17 00:00:00 2001 From: Phillip Smith Date: Tue, 24 Aug 2021 17:55:37 +1000 Subject: [PATCH] initial commit --- Makefile.am | 26 + Makefile.in | 820 ++ aclocal.m4 | 1215 ++ api/c++/Livestatus.cc | 87 + api/c++/Livestatus.h | 50 + api/c++/Makefile | 42 + api/c++/demo.cc | 54 + api/perl/Changes | 164 + api/perl/MANIFEST | 38 + api/perl/META.yml | 37 + api/perl/Makefile.PL | 41 + api/perl/README | 32 + api/perl/examples/dump.pl | 104 + api/perl/examples/test.pl | 143 + api/perl/inc/Module/AutoInstall.pm | 820 ++ api/perl/inc/Module/Install.pm | 470 + api/perl/inc/Module/Install/AutoInstall.pm | 82 + api/perl/inc/Module/Install/Base.pm | 83 + api/perl/inc/Module/Install/Can.pm | 81 + api/perl/inc/Module/Install/Fetch.pm | 93 + api/perl/inc/Module/Install/Include.pm | 34 + api/perl/inc/Module/Install/Makefile.pm | 415 + api/perl/inc/Module/Install/Metadata.pm | 715 ++ api/perl/inc/Module/Install/Win32.pm | 64 + api/perl/inc/Module/Install/WriteAll.pm | 63 + api/perl/lib/Monitoring/Livestatus.pm | 1564 +++ api/perl/lib/Monitoring/Livestatus/INET.pm | 121 + api/perl/lib/Monitoring/Livestatus/MULTI.pm | 922 ++ api/perl/lib/Monitoring/Livestatus/UNIX.pm | 112 + .../t/01-Monitoring-Livestatus-basic_tests.t | 149 + .../t/02-Monitoring-Livestatus-internals.t | 148 + ...03-Monitoring-Livestatus-MULTI-internals.t | 215 + .../t/20-Monitoring-Livestatus-test_socket.t | 329 + api/perl/t/21-Monitoring-Livestatus-INET.t | 30 + api/perl/t/22-Monitoring-Livestatus-UNIX.t | 26 + .../t/30-Monitoring-Livestatus-live-test.t | 472 + ...31-Monitoring-Livestatus-MULTI-live-test.t | 95 + .../t/32-Monitoring-Livestatus-backend-test.t | 106 + ...onitoring-Livestatus-test_socket_timeout.t | 74 + .../t/34-Monitoring-Livestatus-utf8_support.t | 78 + ...-Monitoring-Livestatus-callbacks_support.t | 53 + api/perl/t/97-Pod.t | 9 + api/perl/t/98-Pod-Coverage.t | 23 + api/perl/t/99-Perl-Critic.t | 24 + api/perl/t/perlcriticrc | 286 + api/python/README | 23 + api/python/example.py | 72 + api/python/example_multisite.py | 94 + api/python/livestatus.py | 839 ++ api/python/make_nagvis_map.py | 119 + ar-lib | 270 + compile | 347 + config.guess | 1480 +++ config.h.in | 226 + config.sub | 1801 +++ configure | 10407 ++++++++++++++++ configure.ac | 216 + depcomp | 791 ++ install-sh | 508 + m4/ax_boost_asio.m4 | 115 + m4/ax_boost_base.m4 | 301 + m4/ax_cxx_compile_stdcxx.m4 | 982 ++ missing | 215 + nagios/README | 2 + nagios/broker.h | 223 + nagios/cgiauth.h | 74 + nagios/cgiutils.h | 533 + nagios/comments.h | 128 + nagios/common.h | 501 + nagios/config.h | 336 + nagios/downtime.h | 101 + nagios/locations.h | 44 + nagios/macros.h | 264 + nagios/nagios.h | 822 ++ nagios/nebcallbacks.h | 89 + nagios/neberrors.h | 70 + nagios/nebmods.h | 71 + nagios/nebmodules.h | 103 + nagios/nebstructs.h | 533 + nagios/objects.h | 771 ++ nagios/perfdata.h | 45 + nagios/skiplist.h | 68 + nagios/sretention.h | 37 + nagios/statusdata.h | 202 + nagios4/README | 1 + nagios4/bitmap.h | 156 + nagios4/broker.h | 213 + nagios4/cgiauth.h | 70 + nagios4/cgiutils.h | 479 + nagios4/comments.h | 118 + nagios4/common.h | 531 + nagios4/config.h | 344 + nagios4/defaults.h | 94 + nagios4/dkhash.h | 134 + nagios4/downtime.h | 112 + nagios4/fanout.h | 73 + nagios4/iobroker.h | 175 + nagios4/iocache.h | 181 + nagios4/kvvec.h | 207 + nagios4/libnagios.h | 25 + nagios4/lnag-utils.h | 111 + nagios4/locations.h | 41 + nagios4/logging.h | 90 + nagios4/macros.h | 339 + nagios4/nagios.h | 756 ++ nagios4/nebcallbacks.h | 70 + nagios4/neberrors.h | 67 + nagios4/nebmods.h | 62 + nagios4/nebmodules.h | 94 + nagios4/nebstructs.h | 525 + nagios4/nsock.h | 76 + nagios4/nspath.h | 91 + nagios4/nsutils.h | 111 + nagios4/objects.h | 853 ++ nagios4/perfdata.h | 38 + nagios4/pqueue.h | 185 + nagios4/runcmd.h | 96 + nagios4/shared.h | 55 + nagios4/skiplist.h | 162 + nagios4/snprintf.h | 7 + nagios4/squeue.h | 161 + nagios4/sretention.h | 31 + nagios4/statusdata.h | 199 + nagios4/worker.h | 132 + src/Aggregator.h | 51 + src/AndingFilter.cc | 167 + src/AndingFilter.h | 81 + src/AtomicInt32PointerColumn.h | 48 + src/AttributeListAsIntColumn.cc | 103 + src/AttributeListAsIntColumn.h | 57 + src/AttributeListColumn.cc | 41 + src/AttributeListColumn.h | 62 + src/BitMask.h | 99 + src/BlobColumn.cc | 50 + src/BlobColumn.h | 65 + src/ChronoUtils.h | 142 + src/ClientQueue.cc | 64 + src/ClientQueue.h | 50 + src/Column.cc | 57 + src/Column.h | 95 + src/ColumnFilter.cc | 51 + src/ColumnFilter.h | 64 + src/ColumnsColumn.cc | 35 + src/ColumnsColumn.h | 52 + src/CommentColumn.cc | 76 + src/CommentColumn.h | 68 + src/ContactGroupsColumn.cc | 54 + src/ContactGroupsColumn.h | 49 + src/ContactGroupsMemberColumn.cc | 51 + src/ContactGroupsMemberColumn.h | 50 + src/CountAggregator.cc | 37 + src/CountAggregator.h | 50 + src/CustomTimeperiodColumn.cc | 50 + src/CustomTimeperiodColumn.h | 53 + src/CustomVarsDictColumn.cc | 77 + src/CustomVarsDictColumn.h | 66 + src/CustomVarsDictFilter.cc | 87 + src/CustomVarsDictFilter.h | 56 + src/CustomVarsExplicitColumn.cc | 43 + src/CustomVarsExplicitColumn.h | 52 + src/CustomVarsNamesColumn.cc | 56 + src/CustomVarsNamesColumn.h | 49 + src/CustomVarsValuesColumn.cc | 56 + src/CustomVarsValuesColumn.h | 49 + src/DoubleAggregator.h | 56 + src/DoubleColumn.cc | 48 + src/DoubleColumn.h | 60 + src/DoubleFilter.cc | 76 + src/DoubleFilter.h | 53 + src/DoublePointerColumn.h | 45 + src/DowntimeColumn.cc | 70 + src/DowntimeColumn.h | 66 + src/DowntimeOrComment.cc | 57 + src/DowntimeOrComment.h | 119 + src/DowntimesOrComments.cc | 67 + src/DowntimesOrComments.h | 48 + src/DynamicColumn.cc | 40 + src/DynamicColumn.h | 53 + src/DynamicEventConsoleReplicationColumn.cc | 95 + src/DynamicEventConsoleReplicationColumn.h | 50 + src/DynamicLogwatchFileColumn.cc | 69 + src/DynamicLogwatchFileColumn.h | 53 + src/EventConsoleConnection.cc | 89 + src/EventConsoleConnection.h | 52 + src/FileSystem.h | 34 + src/Filter.cc | 50 + src/Filter.h | 102 + src/FixedIntColumn.h | 46 + src/HostContactsColumn.cc | 60 + src/HostContactsColumn.h | 49 + src/HostFileColumn.cc | 117 + src/HostFileColumn.h | 50 + src/HostGroupsColumn.cc | 60 + src/HostGroupsColumn.h | 54 + src/HostListColumn.cc | 96 + src/HostListColumn.h | 76 + src/HostListStateColumn.cc | 129 + src/HostListStateColumn.h | 92 + src/HostServiceState.cc | 94 + src/HostServiceState.h | 107 + src/HostSpecialDoubleColumn.cc | 133 + src/HostSpecialDoubleColumn.h | 59 + src/HostSpecialIntColumn.cc | 92 + src/HostSpecialIntColumn.h | 56 + src/InputBuffer.cc | 252 + src/InputBuffer.h | 73 + src/IntAggregator.h | 55 + src/IntColumn.cc | 47 + src/IntColumn.h | 64 + src/IntFilter.cc | 149 + src/IntFilter.h | 70 + src/IntPointerColumn.h | 46 + src/ListColumn.cc | 50 + src/ListColumn.h | 68 + src/ListFilter.cc | 145 + src/ListFilter.h | 66 + src/LogCache.cc | 206 + src/LogCache.h | 64 + src/LogEntry.cc | 417 + src/LogEntry.h | 166 + src/Logfile.cc | 252 + src/Logfile.h | 90 + src/Logger.cc | 192 + src/Logger.h | 341 + src/LogwatchListColumn.cc | 84 + src/LogwatchListColumn.h | 57 + src/Makefile.am | 207 + src/Makefile.in | 2779 +++++ src/MetricsColumn.cc | 59 + src/MetricsColumn.h | 54 + src/MonitoringCore.h | 122 + src/NagiosMockup.cc | 114 + src/NullColumn.cc | 45 + src/NullColumn.h | 61 + src/OStreamStateSaver.h | 51 + src/OffsetBoolColumn.cc | 34 + src/OffsetBoolColumn.h | 45 + src/OffsetDoubleColumn.cc | 33 + src/OffsetDoubleColumn.h | 43 + src/OffsetIntColumn.cc | 34 + src/OffsetIntColumn.h | 45 + src/OffsetPerfdataColumn.cc | 32 + src/OffsetPerfdataColumn.h | 47 + src/OffsetSStringColumn.cc | 33 + src/OffsetSStringColumn.h | 43 + src/OffsetStringColumn.cc | 33 + src/OffsetStringColumn.h | 43 + src/OffsetStringHostMacroColumn.cc | 34 + src/OffsetStringHostMacroColumn.h | 48 + src/OffsetStringMacroColumn.cc | 162 + src/OffsetStringMacroColumn.h | 60 + src/OffsetStringServiceMacroColumn.cc | 37 + src/OffsetStringServiceMacroColumn.h | 48 + src/OffsetTimeColumn.cc | 35 + src/OffsetTimeColumn.h | 47 + src/OringFilter.cc | 174 + src/OringFilter.h | 81 + src/OutputBuffer.cc | 96 + src/OutputBuffer.h | 73 + src/PerfdataAggregator.cc | 71 + src/PerfdataAggregator.h | 55 + src/Poller.h | 86 + src/Query.cc | 810 ++ src/Query.h | 154 + src/RegExp.cc | 133 + src/RegExp.h | 59 + src/Renderer.cc | 260 + src/Renderer.h | 341 + src/RendererBrokenCSV.cc | 73 + src/RendererBrokenCSV.h | 98 + src/RendererCSV.cc | 84 + src/RendererCSV.h | 73 + src/RendererJSON.cc | 80 + src/RendererJSON.h | 68 + src/RendererPython.cc | 78 + src/RendererPython.h | 68 + src/RendererPython3.cc | 78 + src/RendererPython3.h | 68 + src/Row.h | 47 + src/ServiceContactsColumn.cc | 60 + src/ServiceContactsColumn.h | 49 + src/ServiceGroupMembersColumn.cc | 126 + src/ServiceGroupMembersColumn.h | 93 + src/ServiceGroupsColumn.cc | 60 + src/ServiceGroupsColumn.h | 54 + src/ServiceListColumn.cc | 145 + src/ServiceListColumn.h | 98 + src/ServiceListStateColumn.cc | 121 + src/ServiceListStateColumn.h | 88 + src/ServiceSpecialDoubleColumn.cc | 86 + src/ServiceSpecialDoubleColumn.h | 51 + src/ServiceSpecialIntColumn.cc | 82 + src/ServiceSpecialIntColumn.h | 56 + src/StatsColumn.cc | 67 + src/StatsColumn.h | 65 + src/StatusSpecialIntColumn.cc | 45 + src/StatusSpecialIntColumn.h | 59 + src/Store.cc | 311 + src/Store.h | 199 + src/StringColumn.cc | 48 + src/StringColumn.h | 65 + src/StringFilter.cc | 97 + src/StringFilter.h | 57 + src/StringPointerColumn.h | 45 + src/StringUtils.cc | 99 + src/StringUtils.h | 84 + src/Table.cc | 101 + src/Table.h | 126 + src/TableColumns.cc | 88 + src/TableColumns.h | 54 + src/TableCommands.cc | 59 + src/TableCommands.h | 45 + src/TableComments.cc | 106 + src/TableComments.h | 45 + src/TableContactGroups.cc | 64 + src/TableContactGroups.h | 45 + src/TableContacts.cc | 142 + src/TableContacts.h | 48 + src/TableDowntimes.cc | 107 + src/TableDowntimes.h | 45 + src/TableEventConsole.cc | 227 + src/TableEventConsole.h | 146 + src/TableEventConsoleEvents.cc | 104 + src/TableEventConsoleEvents.h | 45 + src/TableEventConsoleHistory.cc | 59 + src/TableEventConsoleHistory.h | 43 + src/TableEventConsoleReplication.cc | 48 + src/TableEventConsoleReplication.h | 42 + src/TableEventConsoleRules.cc | 42 + src/TableEventConsoleRules.h | 40 + src/TableEventConsoleStatus.cc | 134 + src/TableEventConsoleStatus.h | 40 + src/TableHostGroups.cc | 188 + src/TableHostGroups.h | 50 + src/TableHosts.cc | 680 + src/TableHosts.h | 49 + src/TableHostsByGroup.cc | 77 + src/TableHostsByGroup.h | 48 + src/TableLog.cc | 208 + src/TableLog.h | 57 + src/TableServiceGroups.cc | 150 + src/TableServiceGroups.h | 50 + src/TableServices.cc | 546 + src/TableServices.h | 49 + src/TableServicesByGroup.cc | 77 + src/TableServicesByGroup.h | 48 + src/TableServicesByHostGroup.cc | 72 + src/TableServicesByHostGroup.h | 49 + src/TableStateHistory.cc | 912 ++ src/TableStateHistory.h | 86 + src/TableStatus.cc | 259 + src/TableStatus.h | 48 + src/TableTimeperiods.cc | 58 + src/TableTimeperiods.h | 43 + src/TimeAggregator.h | 56 + src/TimeColumn.cc | 53 + src/TimeColumn.h | 68 + src/TimeFilter.cc | 150 + src/TimeFilter.h | 70 + src/TimePointerColumn.h | 51 + src/TimeperiodColumn.cc | 55 + src/TimeperiodColumn.h | 43 + src/TimeperiodsCache.cc | 113 + src/TimeperiodsCache.h | 55 + src/Triggers.cc | 83 + src/Triggers.h | 78 + src/auth.cc | 118 + src/auth.h | 53 + src/contact_fwd.h | 37 + src/data_encoding.h | 32 + src/global_counters.cc | 74 + src/global_counters.h | 51 + src/livestatus.h | 30 + src/mk_inventory.cc | 31 + src/mk_inventory.h | 34 + src/mk_logwatch.cc | 48 + src/mk_logwatch.h | 36 + src/module.cc | 1175 ++ src/nagios.h | 61 + src/opids.cc | 132 + src/opids.h | 57 + src/pnp4nagios.cc | 66 + src/pnp4nagios.h | 43 + src/strutil.cc | 85 + src/strutil.h | 34 + src/unixcat.cc | 163 + standalone/config_files.m4 | 2 + 387 files changed, 69168 insertions(+) create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 aclocal.m4 create mode 100644 api/c++/Livestatus.cc create mode 100644 api/c++/Livestatus.h create mode 100644 api/c++/Makefile create mode 100644 api/c++/demo.cc create mode 100644 api/perl/Changes create mode 100644 api/perl/MANIFEST create mode 100644 api/perl/META.yml create mode 100644 api/perl/Makefile.PL create mode 100644 api/perl/README create mode 100755 api/perl/examples/dump.pl create mode 100755 api/perl/examples/test.pl create mode 100644 api/perl/inc/Module/AutoInstall.pm create mode 100644 api/perl/inc/Module/Install.pm create mode 100644 api/perl/inc/Module/Install/AutoInstall.pm create mode 100644 api/perl/inc/Module/Install/Base.pm create mode 100644 api/perl/inc/Module/Install/Can.pm create mode 100644 api/perl/inc/Module/Install/Fetch.pm create mode 100644 api/perl/inc/Module/Install/Include.pm create mode 100644 api/perl/inc/Module/Install/Makefile.pm create mode 100644 api/perl/inc/Module/Install/Metadata.pm create mode 100644 api/perl/inc/Module/Install/Win32.pm create mode 100644 api/perl/inc/Module/Install/WriteAll.pm create mode 100644 api/perl/lib/Monitoring/Livestatus.pm create mode 100644 api/perl/lib/Monitoring/Livestatus/INET.pm create mode 100644 api/perl/lib/Monitoring/Livestatus/MULTI.pm create mode 100644 api/perl/lib/Monitoring/Livestatus/UNIX.pm create mode 100644 api/perl/t/01-Monitoring-Livestatus-basic_tests.t create mode 100644 api/perl/t/02-Monitoring-Livestatus-internals.t create mode 100644 api/perl/t/03-Monitoring-Livestatus-MULTI-internals.t create mode 100644 api/perl/t/20-Monitoring-Livestatus-test_socket.t create mode 100644 api/perl/t/21-Monitoring-Livestatus-INET.t create mode 100644 api/perl/t/22-Monitoring-Livestatus-UNIX.t create mode 100644 api/perl/t/30-Monitoring-Livestatus-live-test.t create mode 100644 api/perl/t/31-Monitoring-Livestatus-MULTI-live-test.t create mode 100644 api/perl/t/32-Monitoring-Livestatus-backend-test.t create mode 100644 api/perl/t/33-Monitoring-Livestatus-test_socket_timeout.t create mode 100644 api/perl/t/34-Monitoring-Livestatus-utf8_support.t create mode 100644 api/perl/t/35-Monitoring-Livestatus-callbacks_support.t create mode 100644 api/perl/t/97-Pod.t create mode 100644 api/perl/t/98-Pod-Coverage.t create mode 100644 api/perl/t/99-Perl-Critic.t create mode 100644 api/perl/t/perlcriticrc create mode 100644 api/python/README create mode 100755 api/python/example.py create mode 100755 api/python/example_multisite.py create mode 100644 api/python/livestatus.py create mode 100755 api/python/make_nagvis_map.py create mode 100755 ar-lib create mode 100755 compile create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.ac create mode 100755 depcomp create mode 100755 install-sh create mode 100644 m4/ax_boost_asio.m4 create mode 100644 m4/ax_boost_base.m4 create mode 100644 m4/ax_cxx_compile_stdcxx.m4 create mode 100755 missing create mode 100644 nagios/README create mode 100644 nagios/broker.h create mode 100644 nagios/cgiauth.h create mode 100644 nagios/cgiutils.h create mode 100644 nagios/comments.h create mode 100644 nagios/common.h create mode 100644 nagios/config.h create mode 100644 nagios/downtime.h create mode 100644 nagios/locations.h create mode 100644 nagios/macros.h create mode 100644 nagios/nagios.h create mode 100644 nagios/nebcallbacks.h create mode 100644 nagios/neberrors.h create mode 100644 nagios/nebmods.h create mode 100644 nagios/nebmodules.h create mode 100644 nagios/nebstructs.h create mode 100644 nagios/objects.h create mode 100644 nagios/perfdata.h create mode 100644 nagios/skiplist.h create mode 100644 nagios/sretention.h create mode 100644 nagios/statusdata.h create mode 100644 nagios4/README create mode 100644 nagios4/bitmap.h create mode 100644 nagios4/broker.h create mode 100644 nagios4/cgiauth.h create mode 100644 nagios4/cgiutils.h create mode 100644 nagios4/comments.h create mode 100644 nagios4/common.h create mode 100644 nagios4/config.h create mode 100644 nagios4/defaults.h create mode 100644 nagios4/dkhash.h create mode 100644 nagios4/downtime.h create mode 100644 nagios4/fanout.h create mode 100644 nagios4/iobroker.h create mode 100644 nagios4/iocache.h create mode 100644 nagios4/kvvec.h create mode 100644 nagios4/libnagios.h create mode 100644 nagios4/lnag-utils.h create mode 100644 nagios4/locations.h create mode 100644 nagios4/logging.h create mode 100644 nagios4/macros.h create mode 100644 nagios4/nagios.h create mode 100644 nagios4/nebcallbacks.h create mode 100644 nagios4/neberrors.h create mode 100644 nagios4/nebmods.h create mode 100644 nagios4/nebmodules.h create mode 100644 nagios4/nebstructs.h create mode 100644 nagios4/nsock.h create mode 100644 nagios4/nspath.h create mode 100644 nagios4/nsutils.h create mode 100644 nagios4/objects.h create mode 100644 nagios4/perfdata.h create mode 100644 nagios4/pqueue.h create mode 100644 nagios4/runcmd.h create mode 100644 nagios4/shared.h create mode 100644 nagios4/skiplist.h create mode 100644 nagios4/snprintf.h create mode 100644 nagios4/squeue.h create mode 100644 nagios4/sretention.h create mode 100644 nagios4/statusdata.h create mode 100644 nagios4/worker.h create mode 100644 src/Aggregator.h create mode 100644 src/AndingFilter.cc create mode 100644 src/AndingFilter.h create mode 100644 src/AtomicInt32PointerColumn.h create mode 100644 src/AttributeListAsIntColumn.cc create mode 100644 src/AttributeListAsIntColumn.h create mode 100644 src/AttributeListColumn.cc create mode 100644 src/AttributeListColumn.h create mode 100644 src/BitMask.h create mode 100644 src/BlobColumn.cc create mode 100644 src/BlobColumn.h create mode 100644 src/ChronoUtils.h create mode 100644 src/ClientQueue.cc create mode 100644 src/ClientQueue.h create mode 100644 src/Column.cc create mode 100644 src/Column.h create mode 100644 src/ColumnFilter.cc create mode 100644 src/ColumnFilter.h create mode 100644 src/ColumnsColumn.cc create mode 100644 src/ColumnsColumn.h create mode 100644 src/CommentColumn.cc create mode 100644 src/CommentColumn.h create mode 100644 src/ContactGroupsColumn.cc create mode 100644 src/ContactGroupsColumn.h create mode 100644 src/ContactGroupsMemberColumn.cc create mode 100644 src/ContactGroupsMemberColumn.h create mode 100644 src/CountAggregator.cc create mode 100644 src/CountAggregator.h create mode 100644 src/CustomTimeperiodColumn.cc create mode 100644 src/CustomTimeperiodColumn.h create mode 100644 src/CustomVarsDictColumn.cc create mode 100644 src/CustomVarsDictColumn.h create mode 100644 src/CustomVarsDictFilter.cc create mode 100644 src/CustomVarsDictFilter.h create mode 100644 src/CustomVarsExplicitColumn.cc create mode 100644 src/CustomVarsExplicitColumn.h create mode 100644 src/CustomVarsNamesColumn.cc create mode 100644 src/CustomVarsNamesColumn.h create mode 100644 src/CustomVarsValuesColumn.cc create mode 100644 src/CustomVarsValuesColumn.h create mode 100644 src/DoubleAggregator.h create mode 100644 src/DoubleColumn.cc create mode 100644 src/DoubleColumn.h create mode 100644 src/DoubleFilter.cc create mode 100644 src/DoubleFilter.h create mode 100644 src/DoublePointerColumn.h create mode 100644 src/DowntimeColumn.cc create mode 100644 src/DowntimeColumn.h create mode 100644 src/DowntimeOrComment.cc create mode 100644 src/DowntimeOrComment.h create mode 100644 src/DowntimesOrComments.cc create mode 100644 src/DowntimesOrComments.h create mode 100644 src/DynamicColumn.cc create mode 100644 src/DynamicColumn.h create mode 100644 src/DynamicEventConsoleReplicationColumn.cc create mode 100644 src/DynamicEventConsoleReplicationColumn.h create mode 100644 src/DynamicLogwatchFileColumn.cc create mode 100644 src/DynamicLogwatchFileColumn.h create mode 100644 src/EventConsoleConnection.cc create mode 100644 src/EventConsoleConnection.h create mode 100644 src/FileSystem.h create mode 100644 src/Filter.cc create mode 100644 src/Filter.h create mode 100644 src/FixedIntColumn.h create mode 100644 src/HostContactsColumn.cc create mode 100644 src/HostContactsColumn.h create mode 100644 src/HostFileColumn.cc create mode 100644 src/HostFileColumn.h create mode 100644 src/HostGroupsColumn.cc create mode 100644 src/HostGroupsColumn.h create mode 100644 src/HostListColumn.cc create mode 100644 src/HostListColumn.h create mode 100644 src/HostListStateColumn.cc create mode 100644 src/HostListStateColumn.h create mode 100644 src/HostServiceState.cc create mode 100644 src/HostServiceState.h create mode 100644 src/HostSpecialDoubleColumn.cc create mode 100644 src/HostSpecialDoubleColumn.h create mode 100644 src/HostSpecialIntColumn.cc create mode 100644 src/HostSpecialIntColumn.h create mode 100644 src/InputBuffer.cc create mode 100644 src/InputBuffer.h create mode 100644 src/IntAggregator.h create mode 100644 src/IntColumn.cc create mode 100644 src/IntColumn.h create mode 100644 src/IntFilter.cc create mode 100644 src/IntFilter.h create mode 100644 src/IntPointerColumn.h create mode 100644 src/ListColumn.cc create mode 100644 src/ListColumn.h create mode 100644 src/ListFilter.cc create mode 100644 src/ListFilter.h create mode 100644 src/LogCache.cc create mode 100644 src/LogCache.h create mode 100644 src/LogEntry.cc create mode 100644 src/LogEntry.h create mode 100644 src/Logfile.cc create mode 100644 src/Logfile.h create mode 100644 src/Logger.cc create mode 100644 src/Logger.h create mode 100644 src/LogwatchListColumn.cc create mode 100644 src/LogwatchListColumn.h create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/MetricsColumn.cc create mode 100644 src/MetricsColumn.h create mode 100644 src/MonitoringCore.h create mode 100644 src/NagiosMockup.cc create mode 100644 src/NullColumn.cc create mode 100644 src/NullColumn.h create mode 100644 src/OStreamStateSaver.h create mode 100644 src/OffsetBoolColumn.cc create mode 100644 src/OffsetBoolColumn.h create mode 100644 src/OffsetDoubleColumn.cc create mode 100644 src/OffsetDoubleColumn.h create mode 100644 src/OffsetIntColumn.cc create mode 100644 src/OffsetIntColumn.h create mode 100644 src/OffsetPerfdataColumn.cc create mode 100644 src/OffsetPerfdataColumn.h create mode 100644 src/OffsetSStringColumn.cc create mode 100644 src/OffsetSStringColumn.h create mode 100644 src/OffsetStringColumn.cc create mode 100644 src/OffsetStringColumn.h create mode 100644 src/OffsetStringHostMacroColumn.cc create mode 100644 src/OffsetStringHostMacroColumn.h create mode 100644 src/OffsetStringMacroColumn.cc create mode 100644 src/OffsetStringMacroColumn.h create mode 100644 src/OffsetStringServiceMacroColumn.cc create mode 100644 src/OffsetStringServiceMacroColumn.h create mode 100644 src/OffsetTimeColumn.cc create mode 100644 src/OffsetTimeColumn.h create mode 100644 src/OringFilter.cc create mode 100644 src/OringFilter.h create mode 100644 src/OutputBuffer.cc create mode 100644 src/OutputBuffer.h create mode 100644 src/PerfdataAggregator.cc create mode 100644 src/PerfdataAggregator.h create mode 100644 src/Poller.h create mode 100644 src/Query.cc create mode 100644 src/Query.h create mode 100644 src/RegExp.cc create mode 100644 src/RegExp.h create mode 100644 src/Renderer.cc create mode 100644 src/Renderer.h create mode 100644 src/RendererBrokenCSV.cc create mode 100644 src/RendererBrokenCSV.h create mode 100644 src/RendererCSV.cc create mode 100644 src/RendererCSV.h create mode 100644 src/RendererJSON.cc create mode 100644 src/RendererJSON.h create mode 100644 src/RendererPython.cc create mode 100644 src/RendererPython.h create mode 100644 src/RendererPython3.cc create mode 100644 src/RendererPython3.h create mode 100644 src/Row.h create mode 100644 src/ServiceContactsColumn.cc create mode 100644 src/ServiceContactsColumn.h create mode 100644 src/ServiceGroupMembersColumn.cc create mode 100644 src/ServiceGroupMembersColumn.h create mode 100644 src/ServiceGroupsColumn.cc create mode 100644 src/ServiceGroupsColumn.h create mode 100644 src/ServiceListColumn.cc create mode 100644 src/ServiceListColumn.h create mode 100644 src/ServiceListStateColumn.cc create mode 100644 src/ServiceListStateColumn.h create mode 100644 src/ServiceSpecialDoubleColumn.cc create mode 100644 src/ServiceSpecialDoubleColumn.h create mode 100644 src/ServiceSpecialIntColumn.cc create mode 100644 src/ServiceSpecialIntColumn.h create mode 100644 src/StatsColumn.cc create mode 100644 src/StatsColumn.h create mode 100644 src/StatusSpecialIntColumn.cc create mode 100644 src/StatusSpecialIntColumn.h create mode 100644 src/Store.cc create mode 100644 src/Store.h create mode 100644 src/StringColumn.cc create mode 100644 src/StringColumn.h create mode 100644 src/StringFilter.cc create mode 100644 src/StringFilter.h create mode 100644 src/StringPointerColumn.h create mode 100644 src/StringUtils.cc create mode 100644 src/StringUtils.h create mode 100644 src/Table.cc create mode 100644 src/Table.h create mode 100644 src/TableColumns.cc create mode 100644 src/TableColumns.h create mode 100644 src/TableCommands.cc create mode 100644 src/TableCommands.h create mode 100644 src/TableComments.cc create mode 100644 src/TableComments.h create mode 100644 src/TableContactGroups.cc create mode 100644 src/TableContactGroups.h create mode 100644 src/TableContacts.cc create mode 100644 src/TableContacts.h create mode 100644 src/TableDowntimes.cc create mode 100644 src/TableDowntimes.h create mode 100644 src/TableEventConsole.cc create mode 100644 src/TableEventConsole.h create mode 100644 src/TableEventConsoleEvents.cc create mode 100644 src/TableEventConsoleEvents.h create mode 100644 src/TableEventConsoleHistory.cc create mode 100644 src/TableEventConsoleHistory.h create mode 100644 src/TableEventConsoleReplication.cc create mode 100644 src/TableEventConsoleReplication.h create mode 100644 src/TableEventConsoleRules.cc create mode 100644 src/TableEventConsoleRules.h create mode 100644 src/TableEventConsoleStatus.cc create mode 100644 src/TableEventConsoleStatus.h create mode 100644 src/TableHostGroups.cc create mode 100644 src/TableHostGroups.h create mode 100644 src/TableHosts.cc create mode 100644 src/TableHosts.h create mode 100644 src/TableHostsByGroup.cc create mode 100644 src/TableHostsByGroup.h create mode 100644 src/TableLog.cc create mode 100644 src/TableLog.h create mode 100644 src/TableServiceGroups.cc create mode 100644 src/TableServiceGroups.h create mode 100644 src/TableServices.cc create mode 100644 src/TableServices.h create mode 100644 src/TableServicesByGroup.cc create mode 100644 src/TableServicesByGroup.h create mode 100644 src/TableServicesByHostGroup.cc create mode 100644 src/TableServicesByHostGroup.h create mode 100644 src/TableStateHistory.cc create mode 100644 src/TableStateHistory.h create mode 100644 src/TableStatus.cc create mode 100644 src/TableStatus.h create mode 100644 src/TableTimeperiods.cc create mode 100644 src/TableTimeperiods.h create mode 100644 src/TimeAggregator.h create mode 100644 src/TimeColumn.cc create mode 100644 src/TimeColumn.h create mode 100644 src/TimeFilter.cc create mode 100644 src/TimeFilter.h create mode 100644 src/TimePointerColumn.h create mode 100644 src/TimeperiodColumn.cc create mode 100644 src/TimeperiodColumn.h create mode 100644 src/TimeperiodsCache.cc create mode 100644 src/TimeperiodsCache.h create mode 100644 src/Triggers.cc create mode 100644 src/Triggers.h create mode 100644 src/auth.cc create mode 100644 src/auth.h create mode 100644 src/contact_fwd.h create mode 100644 src/data_encoding.h create mode 100644 src/global_counters.cc create mode 100644 src/global_counters.h create mode 100644 src/livestatus.h create mode 100644 src/mk_inventory.cc create mode 100644 src/mk_inventory.h create mode 100644 src/mk_logwatch.cc create mode 100644 src/mk_logwatch.h create mode 100644 src/module.cc create mode 100644 src/nagios.h create mode 100644 src/opids.cc create mode 100644 src/opids.h create mode 100644 src/pnp4nagios.cc create mode 100644 src/pnp4nagios.h create mode 100644 src/strutil.cc create mode 100644 src/strutil.h create mode 100644 src/unixcat.cc create mode 100644 standalone/config_files.m4 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])