Imported Upstream version 3.5.1.dfsg
19
.gitignore
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
pkg
|
||||||
|
subst
|
||||||
|
pkginfo
|
||||||
|
Prototype
|
||||||
|
nagios.SPARC.pkg.tar.gz
|
||||||
|
autom4te.cache
|
||||||
|
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
daemon-init
|
||||||
|
Makefile
|
||||||
|
.deps/
|
||||||
|
.libs/
|
||||||
|
*.o
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
*.gcda
|
||||||
|
*.gcno
|
||||||
|
/gmon.out
|
748
Changelog
Normal file
@ -0,0 +1,748 @@
|
|||||||
|
#####################
|
||||||
|
Nagios 3.x Change Log
|
||||||
|
#####################
|
||||||
|
|
||||||
|
3.5.1 - 08/30/2013
|
||||||
|
------------------
|
||||||
|
* Added handler for SIGXFSZ signal (Eric Stanley)
|
||||||
|
* Fixed bug #444: Nagios 3.5.0 problem with macro $ADMINEMAIL$ : @ is converted to %40 after 2 nagios reload (Duplicate of bug #407)
|
||||||
|
* Fixed bug #407: Reloading nagios config causes spaces in notifications to become plus signs (Alexey Dvoryanchikov)
|
||||||
|
* Fixed bug #445: Adding triggered downtime for child hosts causes a SIGSEGV on restart/reload (Eric Stanley)
|
||||||
|
* Fixed bug #375: Freshness expiration never reached and bug #427: freshness threshold doesn't work if it is set long (Scott Wilkerson, Eric Stanley)
|
||||||
|
* Fixed bug #432: Downtime scheduled as "Nagios Process" and not the Users name (Sam Lansing, Eric Stanley)
|
||||||
|
|
||||||
|
3.5.0 - 03/15/2013
|
||||||
|
------------------
|
||||||
|
* Fixed bug #403: The "configuration" page of the webui doesn't use entity encoding when displaying the "command expansion" item (Eric Stanley, Phil Randal)
|
||||||
|
* Fixed bug #424: Nagios Core 3.4.4 seg fault (core dump) on restart after removing config for running service (Eric Stanley)
|
||||||
|
* Updated CGI utility functions to support UTF-8 characters (Eric Stanley)
|
||||||
|
* Fixed bug where selecting Command Expansion from Configuration CGI page would display commands instead (Eric Stanley)
|
||||||
|
* Fixed bug #369: status.cgi crashes with segfault when there are german ulauts (äöüß) in the hostname or the servicename (Eric Stanley)
|
||||||
|
* Fixed bug #418: Scheduled Downtime Notifications Resent On Nagios Restart/reload (Eric Stanley)
|
||||||
|
|
||||||
|
3.4.4 - 01/12/2013
|
||||||
|
------------------
|
||||||
|
* Reenabled check for newer versions of Nagios Core (Mike Guthrie)
|
||||||
|
* Fixed bug #408: service checks get duplicated on reload (Eric Stanley)
|
||||||
|
* Fixed bug #401: segmentation fault on Solaris when parsing unknown timeperiod directives. (Eric Stanley)
|
||||||
|
* Added NULL pointer checks to CGI code. (Eric Stanley)
|
||||||
|
* Fixed buffer overflow vulnerability in CGI code. Thanks to Neohapsis (http://archives.neohapsis.com/archives/fulldisclosure/2012-12/0108.html) for finding this. (Eric Stanley)
|
||||||
|
|
||||||
|
3.4.3 - 11/30/2012
|
||||||
|
------------------
|
||||||
|
* Reverted squeue changes intended for Nagios 4
|
||||||
|
* Reapplied all patches from 3.4.2 release
|
||||||
|
* Applied fix for pagination and sorting on status.cgi #381 (Phil Randal)
|
||||||
|
|
||||||
|
3.4.2 - 11/09/2012
|
||||||
|
------------------
|
||||||
|
FIXES
|
||||||
|
* Fixed issue where deleting a downtime could cause Nagios to crash (Eric Stanley)
|
||||||
|
* Corrected logic so that end times for flexible downtimes are calculated from the downtime start rather than the current time in the case where Nagios is restarted (Eric Stanley)
|
||||||
|
* Fixed issue introduced by fix for bug #124 where flexible downtimes are not taken into account on Nagios restart. (Scott Wilkerson, Eric Stanley)
|
||||||
|
* Fixed bug #247: If a service reports no performance data, the perfdata log file has no line indicating the test. (omnikron@free.fr)
|
||||||
|
* Fixed link for unhandled unreachable host problems on tactical overview page (Rudolf Cejka)
|
||||||
|
* Fixed bug #345 with wild card searches not paging properly on status.cgi (Phil Randal)
|
||||||
|
* Fixed bug #343 on status.cgi where Service Group Summary can potentially show wrong totals (Mark Ziesemer)
|
||||||
|
* Fixed memory leaks on SIGHUP (Carlos Velasco)
|
||||||
|
|
||||||
|
3.4.1 - 05/11/2012
|
||||||
|
------------------
|
||||||
|
FIXES
|
||||||
|
* Double quotes in check_command definition break functionality (#332, reverts #86)
|
||||||
|
|
||||||
|
|
||||||
|
3.4.0 - 05/04/2012
|
||||||
|
------------------
|
||||||
|
ENHANCEMENTS
|
||||||
|
* Added service_check_timeout_state configuration variable (Bill McGonigle)
|
||||||
|
* Permanently remove sleep on run_event == FALSE in main loop (Max <perldork@webwizarddesign.com>)
|
||||||
|
* Reduce notification load by moving notification viability check into notification list creation (Opsview Team)
|
||||||
|
* Added code to apply allow_empty_hostgroup_assignment flag to host and service dependencies (Daniel Wittenberg)
|
||||||
|
* Users can now see hostgroups and servicegroups that contain at least one host or service they are authorized for, instead of having to be authorized for them all (Ethan Galstad)
|
||||||
|
* RSS feed boxes fallback if an error occurs (Ethan Galstad)
|
||||||
|
* RSS feeds no longer block main page load (Mike Guthrie)
|
||||||
|
|
||||||
|
FIXES
|
||||||
|
* Fix $NOTIFICATIONRECIPIENTS$ macro to contain all contacts assigned to host|service, not only notified contacts (Bug #98 Matt Harrington)
|
||||||
|
* Scheduled Downtime Notifications Resent On Nagios Restart/reload (Bug #124 - ricardo)
|
||||||
|
* NOTIFICATIONTYPE MACRO never became CUSTOM (Bug #168 - Alexey Dvoryanchikov)
|
||||||
|
* Plugged minor memory leaks in notification logic
|
||||||
|
|
||||||
|
|
||||||
|
3.3.1 - 07/25/2011
|
||||||
|
------------------
|
||||||
|
ENHANCEMENTS
|
||||||
|
* Added support for same host service dependencies with servicegroups (Mathieu Gagné)
|
||||||
|
* Empty hostgroups referenced from services now optionally generate a warning instead of an error.
|
||||||
|
* Documentation links now point to online resources
|
||||||
|
* Matt Wall's Exfoliation theme is now installed by default. You can reinstall the classic theme with "make install-classicui"
|
||||||
|
* Downtime delete commands made "distributable" by deleting by host group name, host name or start time/comment (Opsview team)
|
||||||
|
* Allow status.cgi to order by "host urgency" (Jochen Bern)
|
||||||
|
* Added news items and quick links to main splash page
|
||||||
|
* Added ability to authenticate to CGIs using contactgroup name (Stephen Gran)
|
||||||
|
|
||||||
|
FIXES
|
||||||
|
* Fixes status.cgi when called with no parameters, where host should be set to all if none specified (Michael Friedrich)
|
||||||
|
* Fixes possible validation error with empty hostgroups/servicegroups (Sven-Göran Bergh)
|
||||||
|
* Performance-data handling and checking is now thread-safe so long as embedded perl is not used.
|
||||||
|
* Children should no longer hang on mutex locks held in parent for localtime() (and similar) calls.
|
||||||
|
* Debug logging is now properly serialized, using soft-locking with a timeout of 150 milliseconds to avoid multiple threads competing for the privilege to write debug info.
|
||||||
|
* Fixed extraneous alerts for services when host is down
|
||||||
|
* Fixed incorrect parsing of multi-line host check results (Jochen Bern)
|
||||||
|
* Fixed bug with passive host checks being incorrectly sent to event brokers as active checks
|
||||||
|
* Fixed bug where passive host check status updates were not being propagated to event brokers
|
||||||
|
* Reverted 'Fix for retaining host display name and alias, as well as service display name' as configuration information stored incorrectly over a reload
|
||||||
|
* Fixed compile warnings for size_t (Michael Friedrich)
|
||||||
|
* Fixed problem where acknowledgements were getting reset when a hard state change occurred
|
||||||
|
* Removed duplicated unlinks for check result files with multiple results
|
||||||
|
* Fixed race condition on flexible downtime commands when duration not set or zero (Michael Friedrich)
|
||||||
|
* Fixed flexible downtime on service hard state change doesn't get triggered/activated (Michael Friedrich)
|
||||||
|
* Fixed XSS vulnerability in config.cgi and statusmap.cgi (Stefan Schurtz)
|
||||||
|
* Fixed segfault when sending host notifications (Michael Friedrich)
|
||||||
|
* Fixed bug where unauthorized contacts could issue hostgroup and servicegroup commands (Sven Nierlein)
|
||||||
|
|
||||||
|
WARNINGS
|
||||||
|
|
||||||
|
|
||||||
|
3.2.3 - 10/03/2010
|
||||||
|
------------------
|
||||||
|
ENHANCEMENTS
|
||||||
|
|
||||||
|
FIXES
|
||||||
|
* Fixes problem where disabling all active hosts/services was not taking effect
|
||||||
|
* Fixes for compiler warnings (code cleanup by Stephen Gran)
|
||||||
|
* Fixes for format errors in event handler logging (Guillaume Rousse)
|
||||||
|
* Fixed incorrect info in sample nagios.cfg file for state_retention_file (Michael Friedrich)
|
||||||
|
* Fixed broker_event_handler() to return ERR if data is NULL (Michael Friedrich)
|
||||||
|
|
||||||
|
WARNINGS
|
||||||
|
|
||||||
|
|
||||||
|
3.2.2 - 09/01/2010
|
||||||
|
------------------
|
||||||
|
ENHANCEMENTS
|
||||||
|
* Patch to new_mini_epn to allow any command line length without breaking on extra trailing or leading whitespace (Ray Bengen)
|
||||||
|
* Patch to mini_epn to allow any command line length (Thomas Guyot-Sionnest)
|
||||||
|
* Patch to speed up loading of state retention data (Matthieu Kermagoret)
|
||||||
|
* Custom notifications are now suppressed during scheduled downtime (Sven Nierlein)
|
||||||
|
* Added code to warn user about exit code of 126 meaning plugin is not executable (bug #153)
|
||||||
|
* Scheduled downtime can now start on SOFT error states (bug #47)
|
||||||
|
* Main window frame URL can now be specify with a "corewindow=" parameter
|
||||||
|
* Improved config CGI shows commands, command args in an easier to use manner (Jochen Bern)
|
||||||
|
* Added ability for NEB modules to override execution of event handlers (Sven Nierlein)
|
||||||
|
* Custom macros are no longer cleaned/stripped as they are user-defined and should be trusted (Peter Morch)
|
||||||
|
|
||||||
|
FIXES
|
||||||
|
* Fix for choosing next valid time on day of DST change when clocks go one hour backwards
|
||||||
|
* Fix for nagios now erroring when "Error: Could not find any contactgroup matching..." displayed
|
||||||
|
* Fix tap tests for Solaris 10 and newer versions of Test::Harness
|
||||||
|
* Fix for notifications not being sent out when scheduled downtime is cancelled (Daniel Pouzzner)
|
||||||
|
* Fix for first notification delay being calculated incorrectly, and notifications potentially going out early (Pawel Malachowski)
|
||||||
|
* Fix for text of scheduling downtime of all services on a host (Holger Weiss)
|
||||||
|
* Fix for services inheriting notification period from hosts if not defined (Gordon Messmer)
|
||||||
|
* Fix for incorrect service states on host failures (bug #130 Petya Kohts)
|
||||||
|
* Fix for incorrect service state attributes being set on host failures (bug #128 Petya Kohts)
|
||||||
|
* Fix for non-scheduled hosts and services not being updated in NDOUtils
|
||||||
|
* Fix for typos in TAC, CMD CGIs (bugs #150, #144, #148)
|
||||||
|
* Fix for types in documentation (bugs #145, #105, #106)
|
||||||
|
* Fix for incorrect host state counts in status CGI when viewing servicegroups (bug #72)
|
||||||
|
* Fix for new Splunk integration query parameters (bug #136)
|
||||||
|
* Fix for extra field header in availability CSV export (bug #113)
|
||||||
|
* Fix for macro processing code modifying input string (Jochen Bern)
|
||||||
|
* Fix for update check API
|
||||||
|
* Fix for CGI speedup when persistent=0 for comments
|
||||||
|
* Fix for event execution loop re-scheduling host checks instead of executing them if service checks are disabled (bug #152)
|
||||||
|
* Fix for segfaults on Solaris (Torsten Huebler)
|
||||||
|
* Fix for incorrect comment expiration times being passed to event broker (Mattieu Kermagot)
|
||||||
|
* Doc updates related to cleaning of custom macros (Peter Valdemar Morch)
|
||||||
|
* Fix to sample notify-service-by-email command (bug #62)
|
||||||
|
* Fix for retaining host display name and alias, as well as service display name (Folkert van Heusden)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.2.1 - 03/09/2010
|
||||||
|
------------------
|
||||||
|
ENHANCEMENTS
|
||||||
|
* Link to allow scheduling downtime for all services on a host (Hendrik Baecker)
|
||||||
|
* Speedup to CGIs when lots of comments or downtimes in status.dat file (Jonathan Kamens)
|
||||||
|
* Patch for new_mini_epn to allow for any command line length without breaking extra trailing or leading whitespace (Ray Bengen)
|
||||||
|
|
||||||
|
FIXES
|
||||||
|
* Fix for incorrect scheduling when time has gone back an hour (partial fix for 24x7)
|
||||||
|
* Fix for compile on Fedora Core 3 (bug #0000082)
|
||||||
|
* Fix for compile on Solaris
|
||||||
|
* Fix for logging test, which was not timezone aware (bug #0000077 - Allan Clark)
|
||||||
|
* Trivial cleanups for autoconf (Allan Clark)
|
||||||
|
* Fix for CSS validation of padding: X
|
||||||
|
* Fix for documentation re: case-insensitive nature of custom variables (Marc Powell)
|
||||||
|
* Fix for template configurations which use negated wildcards (Tim Wilde)
|
||||||
|
|
||||||
|
WARNINGS
|
||||||
|
* N/A
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.2.0 - 08/12/2009
|
||||||
|
------------------
|
||||||
|
* Fix for read-only permissions bug in CGIs that caused problems viewing comments (bug #0000029)
|
||||||
|
* Fix for incorrect CGI reports (availability, trends, etc.) when reporting period spans Daylight Savings Time (bug #0000046)
|
||||||
|
* Fix for detection of truecolor support in GD library (Lars Hecking)
|
||||||
|
* Reverted to use --datadir configure script option instead of the more recently introduced --datarootdir option
|
||||||
|
* Status and retention files are now flushed/synced to disk to prevent incomplete information being displayed in CGIs
|
||||||
|
* Fix for incorrect next service check time calculation when Nagios is reloaded with different timeperiod ranges
|
||||||
|
* Updated Fedora quickstart guide to indicate PHP requirements
|
||||||
|
* Known issue: Service checks that are defined with timeperiods that contain "exclude" directives are incorrectly re-scheduled. Don't use these for now - we'll get this fixed for 3.4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.1.2 - 06/23/2009
|
||||||
|
------------------
|
||||||
|
* Fix for CPU hogging in service and host check scheduling logic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.1.1 - 06/22/2009
|
||||||
|
------------------
|
||||||
|
* New "important check command" flag for use in service templates, to aid configuration in distributed environments
|
||||||
|
* Fix for nagios validation error when no services defined
|
||||||
|
* Fix for stylesheet link
|
||||||
|
* Fix for extinfo.cgi error message when cgi.cfg doesn't exist
|
||||||
|
* Fix for notifications.cgi where Update button on right didn't retain host information when no host= was in query parameters
|
||||||
|
* Fix for potential bug where a contactgroup with no members could cause parsing errors
|
||||||
|
* Fix for W3 validation for history.cgi
|
||||||
|
* Fix for W3 validation for extinfo.cgi
|
||||||
|
* Fix for nagiostats to return non-zero with failures in MRTG mode
|
||||||
|
* Added t/ directory for tests. Use make test to run. Requires perl on development server
|
||||||
|
* Fix for duplicate event_id attributes in status and retention data
|
||||||
|
* Fix for duplicate unlink() during check processing
|
||||||
|
* Added missing check period column to host config display (CGI)
|
||||||
|
* Fix for embedded Perl initialization under FreeBSD
|
||||||
|
* Fix for incorrect re-initialization of mutext after program restart
|
||||||
|
* Fix for incorrect weighting in host flap detection logic
|
||||||
|
* Added libtap to distribution. Use ./configure --enable-libtap to compile
|
||||||
|
* nagios.log permissions are now kept after log rotation
|
||||||
|
* Fix for "Max concurrent service checks (X) has been reached" messages - will now push services 5 + random(10) seconds ahead for retry
|
||||||
|
* Fix for removing old HTML files for web frontend that are now replaced with PHP equivalents (index/main/side.html)
|
||||||
|
* Fix for incorrect service history link text in CGIs
|
||||||
|
* Fix for useless code loop in netutils.c
|
||||||
|
* Fix for potential divide by zero in event scheduling code
|
||||||
|
* Fix for trailing backslash in plugin output causing memory corruption in CGIs
|
||||||
|
* Fix for bug that could affect host/service scheduling during clock time skew or changes to timeperod definitions between restarts
|
||||||
|
* Leading whitespace from continuation lines in configuration files is now stripped out
|
||||||
|
* Fix for bug where pipe (used by IPC) file descriptors get inherited by child processed (e.g. event handlers) (bug #0000026)
|
||||||
|
* Fix for failure to daemonize - Nagios now bails (bug #0000011)
|
||||||
|
* Fix for notifications about flapping starting not processed properly by retention data
|
||||||
|
* Patch to add transparency to statusmap icons for truecolor images
|
||||||
|
* Patch to add read-only permissions to extinfo CGI
|
||||||
|
* Security fix for statuswml.cgi where arbitrary shell injection was possible
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.1.0 - 01/25/2009
|
||||||
|
------------------
|
||||||
|
* Added automatic update check functionality - runs once a day to check for new Nagios releases
|
||||||
|
* Splash screen on web UI now indicates whether a new update is available (requires that update checks are enabled)
|
||||||
|
* Updates to nagiostats utility for faster execution if using external stats file
|
||||||
|
* Added a bit more verbosity to config verification
|
||||||
|
* Fixed bug in logging event handlers
|
||||||
|
* Fix to prevent debug output from being shown when Nagios is compiled with embedded Perl interpreter
|
||||||
|
* Fix for CPU hogging issues on OpenBSD
|
||||||
|
* Fix to RPM spec file for sample configuration files
|
||||||
|
* Fix for bug in time calculation routines that could cause notification, reporting, and check scheduling anomalies
|
||||||
|
* Fix for scheduling forced service checks from web interface
|
||||||
|
* Minor mods for frameset base for HTML compliance (more fixes coming soon)
|
||||||
|
* Fix for bug in handling of hard host and service problem states during restarts that could incorrectly set current check attempt and adversely affect notifications, etc.
|
||||||
|
* Fix for bug in timeperiod calculation of year/month rollovers and display of fixed calendar dates in web interface
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0.6 - 12/01/2008
|
||||||
|
------------------
|
||||||
|
* Fix for CGI submission of external commands (writing newlines and submitting service comments)
|
||||||
|
* Fix for Apache group membership in RPM spec file
|
||||||
|
* Fix for improper notification propagation command processing
|
||||||
|
* Better out-of-disk-space error handling when writing retention and status files
|
||||||
|
* Disabled adaptive check and eventhandler commands for security reasons
|
||||||
|
* Fix for reading output from system commands (event handlers, etc) that have timed out
|
||||||
|
* Added wildcard host matching in CGIs
|
||||||
|
* Fixes for playing audio alerts in CGIs
|
||||||
|
* Fix for incorrect host status links in status CGI when viewing hostgroup summary
|
||||||
|
* Added support for x509 cert authentication in the CGIs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0.5 - 11/04/2008
|
||||||
|
------------------
|
||||||
|
* Security fix for Cross Site Request Forgery (CSRF) bug reported by Tim Starling.
|
||||||
|
* Sample audio files for CGIs removed from distribution
|
||||||
|
* Fix for mutliline config file continuation bug
|
||||||
|
* Minor fix to RPM spec file
|
||||||
|
* Fix for AIX compiler warnings
|
||||||
|
* Minor sample config file fix
|
||||||
|
* Added documentation on CGI security issues
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0.4 - 10/15/2008
|
||||||
|
------------------
|
||||||
|
* Fix for properly terminating plugins when parent processes get killed (e.g. using 'killall nagios' with check_timeout plugins running)
|
||||||
|
* Fix for event broker callback when service notifications are disabled
|
||||||
|
* Fix for scheduling scheduling servicegroup downtime with 'hosts too' option in CGIs
|
||||||
|
* Fix for segfault under Solaris with NULL plugin output
|
||||||
|
* Fixes for bugs in sample event handlers - stop/start active service checks and enable notifications
|
||||||
|
* Cosmetic fix for logging of notifications
|
||||||
|
* Fix for high CPU utilization under OS X
|
||||||
|
* Fix for host/service name encoding in CGIs (trends and availability reports, etc.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0.3 - 06/25/2008
|
||||||
|
------------------
|
||||||
|
* Typo fix in object config routines
|
||||||
|
* Segfault fix in history CGI
|
||||||
|
* Fix for bug in retention of contact notification options
|
||||||
|
* Fix for bug in calculation of negative (month) days in timeperiod definitions
|
||||||
|
* Fix for debug logging of notifications
|
||||||
|
* Fix for encoding host and servicegroup names in trends and availability CGIs
|
||||||
|
* Fix for checking for abnormal termination of host checks
|
||||||
|
* Fix for spurious orphaned host check errors with non-scheduled hosts
|
||||||
|
* Fix for url encoding null string in CGIs (caused status CGI segfault)
|
||||||
|
* Fix for encoding URLs in macros
|
||||||
|
* Fix for bug in handling of contact groups in escalation definitions
|
||||||
|
* Changes to service check event broker logic (DNX patches)
|
||||||
|
* Minor doc updates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0.2 - 05/19/2008
|
||||||
|
------------------
|
||||||
|
* Minor bug fixes in CGIs to ensure extra host/servicegroup url strings are terminated properly
|
||||||
|
* Minor bug fix in navigation frame link for unhandled service problems
|
||||||
|
* Better error logging during fork() errors
|
||||||
|
* Embedded Perl is now disabled by default
|
||||||
|
* Fixed bug in parsing host dependencies
|
||||||
|
* Added note to Makefile about 'make install-webconf' option
|
||||||
|
* Fixed bug in config CGI where active host check attributes were not displayed properly
|
||||||
|
* Fixed bug in status CGI where sounds were not played for passive service problems
|
||||||
|
* Fixed sample script for distributed monitoring
|
||||||
|
* Updated p1.pl to allow for 4KB lines in Perl plugin output under epn
|
||||||
|
* Fixed bug in command for disabling contact notifications
|
||||||
|
* Fix for bugs in host and service orphan check logic
|
||||||
|
* Fix for 'make install' functionality for contrib directory
|
||||||
|
* Fix for host problem links in CGI status summary view
|
||||||
|
* Fix for properly escaping macros containing URLs
|
||||||
|
* Patches for possible XSS vulnerability in CGIs (CVE-2007-5803) - Florian Weimer & SUSE Linux team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0.1 - 04/01/2008
|
||||||
|
-------------------
|
||||||
|
* Fixed bug in trends CGI with user not being authorized for hosts/services
|
||||||
|
* Fixed bug in status CGI with page layout messing up when sounds enabled
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0 - 03/13/2008
|
||||||
|
-------------------
|
||||||
|
* Faster program startup times (especially in large installs) with new object lookup code
|
||||||
|
* Fix for special contact inheritance rules in host and service escalations
|
||||||
|
* Fix for threading-related bugs that resulted in checks failing under NetBSD
|
||||||
|
* Configure script fix
|
||||||
|
* Fix for bug in processing $CONTACTADDRESSx$ macros
|
||||||
|
* Documentation fixes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0rc3 - 02/26/2008
|
||||||
|
-------------------
|
||||||
|
* Fix for passive service check stats bugs in nagiostats
|
||||||
|
* Nagios no longer warns or errors when encountering host/contact/service groups with empty memberships
|
||||||
|
* Debugging info fix in notification logic
|
||||||
|
* Fix for multiline support in config files (again)
|
||||||
|
* Fix for stripping illegal chars in output, perfdata macros
|
||||||
|
* Patch to allow non-ASCII characters in notifications, etc.
|
||||||
|
* Fix for bug in on-demand service macros with blank/null host names
|
||||||
|
* Fix for cleaning up zombie child processes if large installation tweaks disabled and fork twice option disabled
|
||||||
|
* Fix for incorrect total checks counts in nagiostats
|
||||||
|
* Fix for segfault if embedded Perl support compiled in, but disabled by config file option
|
||||||
|
* Smarter host check logic to reduce (uncached) on-demand host checks during "stable" service problems
|
||||||
|
* Fix for recursive subgroup membership for host/service/contact groups
|
||||||
|
* Fix for renaming/moving files on network file systems
|
||||||
|
* New flap detection startup logic speedups when large installations tweaks enabled
|
||||||
|
* Speed improvements during startup routines when using precached config
|
||||||
|
* Speed improvements in reading retention data during startup
|
||||||
|
* Safer loading mechanism for NEB modules to prevent segfaults in Nagios
|
||||||
|
* Fix for segfault in CGIs when converting object names with extended ASCII characters to URLs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0rc2 - 01/29/2008
|
||||||
|
-------------------
|
||||||
|
* Changed embedded audio MIME types in CGIs to "application/wav"
|
||||||
|
* Fixed bug in sample helloworld NEB module
|
||||||
|
* Modified p1.pl to allow for multiline-line output of Perl plugins under embedded Perl interpreter (epn)
|
||||||
|
* Fix for incorrect environment variables names for custom host and contact macros
|
||||||
|
* Fix for external command file thread polling code
|
||||||
|
* Fix for cfg_dir directive not working on Solaris
|
||||||
|
* Fixed segfault in extinfo CGI when passed an invalid service description/name
|
||||||
|
* Fixed bug in summary CGI with reports on specific hosts
|
||||||
|
* Fix for writing check result files under Cygwin
|
||||||
|
* Fix for not building sample helloworld.o event broker module if event broker is disabled by configure script
|
||||||
|
* Fix to sample event handler scripts
|
||||||
|
* Fix for handling plugin output with escaped newlines and backslashes
|
||||||
|
* Fix for bug in service and host event scheduling logic
|
||||||
|
* Fix for reversed object sort order when using fast startup options
|
||||||
|
* Fix for bug with notification commands not being run if notifications were not logged
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0rc1 - 12/17/2007
|
||||||
|
-------------------
|
||||||
|
* Fixed bug where status log was left after a restart with faulty config
|
||||||
|
* Fix for compilation bug on systems that don't support setenv() (e.g. Solaris)
|
||||||
|
* Support for line continuation/breaks in config files - end lines with one backslash (\) to continue on next line
|
||||||
|
* Fixed bug with not deleting old check result files that contained results for invalid host/service
|
||||||
|
* Fixed bug with init script option to check Nagios config
|
||||||
|
* Auto-filled comment/author fields for acknowledging problems through WAP interface
|
||||||
|
* Fixed bug with processing of CONTACTGROUPNAMES, NOTES, NOTESURL, and ACTIONURL macros
|
||||||
|
* Doc fix regarding soft state dependencies
|
||||||
|
* Fix for segfault in event broker module code
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0b7 - 11/23/2007
|
||||||
|
------------------
|
||||||
|
* Memory leak fix in macro code
|
||||||
|
* Added use_timezone option to allow Nagios instances to run in non-native timezones
|
||||||
|
* Fix for encoding HTML characters in CGIs
|
||||||
|
* Fix for unimplemented $LASTHOSTSTATE$, $LASTHOSTSTATEID$, $LASTSERVICESTATE$, and $LASTSERVICESTATEID$ macros
|
||||||
|
* Fixes for memory leaks with passive check, performance data routines
|
||||||
|
* Makefile fixes
|
||||||
|
* Code cleanup, fixes for compiler warnings
|
||||||
|
* Fix to prevent FLAPPINGSTART notifications from incorrectly being resent after program restarts
|
||||||
|
* Added free_child_process_memory and child_processes_fork_twice options for performance tweaks
|
||||||
|
* Fix for bug in processing of on-demand service macros
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0b6 - 10/31/2007
|
||||||
|
------------------
|
||||||
|
* Logging API revamp, cleanup
|
||||||
|
* Misc internal performance improvements
|
||||||
|
* Bug fix with attempting to access an uninitalized mutex if external commands are disabled
|
||||||
|
* Updates to .cvsignore files
|
||||||
|
* Fix for embedded Perl interpreter to recache scripts when they're modified
|
||||||
|
* Fix for cancelling inheritance with 'null' in various object directives
|
||||||
|
* Additional functionality of additive inheritance feature
|
||||||
|
* Fixed bug where missing host/servicegroups in object definitions didn't always generate errors
|
||||||
|
* Increased max plugin output length cap from 4kb to 8kb
|
||||||
|
* Caching of Perl scripts now enabled by default if embedded Perl interpreter is compiled in
|
||||||
|
* Fix for segfault when contact definitions had no notification timeperiods defined
|
||||||
|
* Retention of host/service check scheduling options
|
||||||
|
* Fix for race condition when freshening host and service check results
|
||||||
|
* Added null -b option to install-sh for Solaris so install scripts don't break
|
||||||
|
* Added .gitignore files for git users
|
||||||
|
* Added new external commands to change notification period for host, services, and contact on-the-fly
|
||||||
|
* Added new external commands to change modified object attributes (affecting data retention logic)
|
||||||
|
* Added $ISVALIDTIME:$ and $NEXTVALIDTIME:$ on-demand macros
|
||||||
|
* Added enable_environment_macros option to determine whether or not macros are set as environment vars
|
||||||
|
* Major overhaul (read: complete rewrite) of macro code, so macros are now only computed when found
|
||||||
|
* Summary macros are now available as regular (non-environment) macros if requested when large installation tweaks are enabled
|
||||||
|
* Bug fix for scheduling hostgroup host downtime through web interface
|
||||||
|
* Better error logging when failing to rename/move files
|
||||||
|
* Added $LASTHOSTSTATE$, $LASTHOSTSTATEID$, $LASTSERVICESTATE$, and $LASTSERVICESTATEID$ macros
|
||||||
|
* Addition of object pointers to event broker module data structures (may require event broker module rebuilds)
|
||||||
|
* Spec file changes to better support RPM builds on 64-bit systems
|
||||||
|
* Possible fix for Unicode html encoding errors in CGIs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0b5 - 10/08/2007
|
||||||
|
------------------
|
||||||
|
* Minor bug fix in CSS files
|
||||||
|
* Bug fix in sample config files
|
||||||
|
* Fix for recovery notifications not being sent out when first_notification_delay option used in host/service definitions
|
||||||
|
* Fix for ochp commands not running properly
|
||||||
|
* Special additive inheritance rule: escalation contact(group)(s) that begin with '+' will now inherit from associated host/service definition if not inheriting from another escalation template
|
||||||
|
* Status file is no longer deleted during restarts due to a SIGHUP or external command
|
||||||
|
* Improvement in service flap detection logic
|
||||||
|
* Added additional_freshness_latency config file directive
|
||||||
|
* Improvements in freshness check logic
|
||||||
|
* Temporarily removed $SERVICEGROUPMEMBERS$ macro, as it was causing crashes for some users (this need further investigation)
|
||||||
|
* Added $EVENTSTARTTIME$ macro to indicate time Nagios started processing events (checks, etc.)
|
||||||
|
* Added use_pending_states option to CGI config file to determine displayed state of hosts/services that have not been checked
|
||||||
|
* Workaround to prevent browsers from incorrectly using cached statusmap image on page refresh
|
||||||
|
* Fix for incorrect latency calculations for passive host/service checks
|
||||||
|
* Added passive check latency stats to nagiostats
|
||||||
|
* Added support for relative paths in config_file and config_dir directives
|
||||||
|
* Fix for compile error under Solaris
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0b4 - 09/27/2007
|
||||||
|
------------------
|
||||||
|
* New macros: $HOSTGROUPMEMBERS$, $HOSTGROUPNOTES$, $HOSTGROUPNOTESURL$, $HOSTGROUPACTIONURL$, $SERVICEGROUPMEMBERS$, $SERVICEGROUPNOTES$, $SERVICEGROUPNOTESURL$, $SERVICEGROUPACTIONURL$, $CONTACTGROUPALIAS$, $CONTACTGROUPMEMBERS$, $NOTIFICATIONRECIPIENTS$, $NOTIFICATIONAUTHOR$, $NOTIFICATIONAUTHORNAME$, $NOTIFICATIONAUTHORALIAS$, $NOTIFICATIONCOMMENT$
|
||||||
|
* Removed host/service downtime author/comment macros introduced in 3.0b2 in favor of more generic $NOTIFICATION...$ macros
|
||||||
|
* Fix for segfault when cancelling active scheduled host downtime
|
||||||
|
* Macro code cleanup
|
||||||
|
* Added on-demand contact and contactgroup macro support
|
||||||
|
* More complete (but still partial) support for macros in CGIs ($xNOTES$, $xNOTESURL$, and $xACTIONURL$ macros)
|
||||||
|
* Fixed bug in config CGI with displaying incorrect notification interval for escalations
|
||||||
|
* Added new 'check' option to init script to verify configuration
|
||||||
|
* Added custom host and service notifications, with option to force the notifications and broadcast them to all contacts
|
||||||
|
* Fix for on-demand/cached host check statistics
|
||||||
|
* Fixed bug where null host check command would cause high CPU utilization
|
||||||
|
* Alias, if not specified, now defaults to object name in host, hostgroup, servicegroup, contact, and contactgroup definitions
|
||||||
|
* Fixed bug with excluding hosts, services, and contacts with bang (!) in object definitions
|
||||||
|
* Fixed bug in nagiostats with NULL mrtg data arguments printing bogus string
|
||||||
|
* Added custom delimiter option in nagiostats output (useful for CSV output)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0b3 - 08/30/2007
|
||||||
|
------------------
|
||||||
|
* Minor bug fix for debug logging of macros
|
||||||
|
* Version number is now printed in CGI pages
|
||||||
|
* HTML documentation cleanup (HTML Tidy, link checking, etc.)
|
||||||
|
* Fixed bug where notifications would not be sent out host/service contact group members
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0b2 - 08/29/2007
|
||||||
|
------------------
|
||||||
|
* Fix for some sample config files getting installed with .sample extension
|
||||||
|
* Improvements to the host check logic performance (more use of cached and parallel checks)
|
||||||
|
* Minor bug fix with notification timeout error messages
|
||||||
|
* Fix bug with logging of passive host and service check results
|
||||||
|
* Fixed bug with warning about no contactgroups being defined
|
||||||
|
* Internal data structure cleanups
|
||||||
|
* New macros: $SERVICEISVOLATILE$, $TOTALHOSTSERVICES$, $TOTALHOSTSERVICESOK$, $TOTALHOSTSERVICESWARNING$, $TOTALHOSTSERVICESUNKNOWN$, $TOTALHOSTSERVICESCRITICAL$, $HOSTDOWNTIMEAUTHOR$, $HOSTDOWNTIMEAUTHORNAME$, $HOSTDOWNTIMEAUTHORALIAS$, $HOSTDOWNTIMECOMMENT$, $SERVICEDOWNTIMEAUTHOR$, $SERVICEDOWNTIMEAUTHORNAME$, $SERVICEDOWNTIMEAUTHORALIAS$, $SERVICEDOWNTIMECOMMENT$
|
||||||
|
* Added 'lock_author_names' option to CGI config file to prevent alteration of author names
|
||||||
|
when submitting comments, scheduled downtime, etc.
|
||||||
|
* Fix for concatentation of multiline plugin perfdata
|
||||||
|
* Added status CGI host/service property filters for hard and soft states
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0b1 - 07/31/2007
|
||||||
|
------------------
|
||||||
|
* Fixed bug with processing epn directives in Perl plugins
|
||||||
|
* Fixed bug with check_result_path config option being ignored
|
||||||
|
* Added $MAXHOSTATTEMPTS$ and $MAXSERVICEATTEMPTS$ macros
|
||||||
|
* Fixed bug with incorrect output returned from embedded Perl plugins
|
||||||
|
* Fixed bug where status data file was not read by CGIs using mmap()
|
||||||
|
* Fix for CGI segfault
|
||||||
|
* Program status now updated at least every 5 seconds for addons that watch NDOUtils DB
|
||||||
|
* Added escape_html_tags option to CGI config file to escape HTML tags in plugin output
|
||||||
|
* Added optional integration with Splunk into the CGIs
|
||||||
|
* Added new action and notes URL target frame options to CGI config file
|
||||||
|
* Added new 'exclude' option to timeperiod definitions for easy on-call rotation definitions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0a5 - 06/19/2007
|
||||||
|
------------------
|
||||||
|
* Fixed problem with multiline long plugin output and Perl plugin output
|
||||||
|
* Fixed compilation problem with embedded Perl
|
||||||
|
* More debug/trace log functionality
|
||||||
|
* Added new 'passive_host_checks_are_soft' config option
|
||||||
|
* Fixed bug with host notifications occurring during soft host states
|
||||||
|
* Fixed bug in processing multiple check results contained in a single file
|
||||||
|
* Expanded timeperiod definitions to allow for day/date exceptions
|
||||||
|
* Changes to sample config files and installation location
|
||||||
|
* Changed debug file format to include current pid
|
||||||
|
* Added 'initial_state' option to host and service definitions to allow for non-UP/OK initial states
|
||||||
|
* Minor changes to freshness threshold calculation
|
||||||
|
* Documentation updates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0a4 - 05/08/2007
|
||||||
|
------------------
|
||||||
|
* Fix for segfault fix when low priority event queue's only item is removed
|
||||||
|
* Added test for writeability of temp directory during configuration test
|
||||||
|
* Fix for unescaping backslashes in plugin output in the CGIs
|
||||||
|
* Removed check_result_buffer_slots option from main configuration file
|
||||||
|
* New IPC method for passing host/service check results back to main daemon
|
||||||
|
* Added check_result_path option to set path used to store check results
|
||||||
|
* Added max_check_result_file_age option to control processing of check results in older files
|
||||||
|
* Added new --with-temp-dir option to configure script
|
||||||
|
* Removed legacy 2.x host check logic and use_old_host_check_logic option
|
||||||
|
* Removed DEBUGx options from configure script
|
||||||
|
* Added new debug/trace log functionaltiy (only partially complete)
|
||||||
|
* Fixed compilation error under OSX
|
||||||
|
* Fix for SIGTERMs being seen as SIGEXITs, non-logging of SIGTERMs/shutdowns
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0a3 - 04/10/2007
|
||||||
|
------------------
|
||||||
|
* Configure script fix for no mail program found/installed on system
|
||||||
|
* Fix for compilation warnings about implicit declaration of round() - may (strangely enough) also
|
||||||
|
fix segfaults that were occuring on some systems
|
||||||
|
* Added detection of Apache conf.d directory and 'make install-webconf' functionality
|
||||||
|
* Configure script option bug fixes for cygwin and embedded perl
|
||||||
|
* Added buffer stats and check statistics to performance information in extinfo CGI
|
||||||
|
* Hostgroup and servicegroup definitions now have notes, notes_url, and action_url directives
|
||||||
|
* Patch for incorrect time down percentage in availability CGI
|
||||||
|
* Command definitions and host/service plugin perfdata with HTML should now be escaped in CGIs
|
||||||
|
* Updated init script to fix a race condition during restarts
|
||||||
|
* Documentation updates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0a2 - 03/27/2007
|
||||||
|
------------------
|
||||||
|
* Added warning about aggregate_status_updates directive being deprecated.
|
||||||
|
* Added new "p" option to host/service_perfdata_file_mode directives for pipes.
|
||||||
|
* Fix for incorrect performance data file write/append mode options
|
||||||
|
* Regular expression matching in object config files now also triggered by '+' and '\.'
|
||||||
|
* Added support for extended regular expression matching in object config files
|
||||||
|
* Fix for incorrect processing of y_2d coordinates for host objects in statusmap layout
|
||||||
|
* Fix for current status of hosts with no check command defined
|
||||||
|
* SIGSEGV signals should now be logged again (broken in 3.0a1)
|
||||||
|
* Added warning for invalid temp_path directory
|
||||||
|
* Documentation bug fixes and updates
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0a1 - 03/06/2007
|
||||||
|
------------------
|
||||||
|
Here are all the changes since Nagios 2.x:
|
||||||
|
|
||||||
|
* Adaptive monitoring:
|
||||||
|
- Check timeperiod can now be modified on-the-fly
|
||||||
|
|
||||||
|
* Notification changes:
|
||||||
|
- Added first_notification_delay to host and object definitions to delay first notification
|
||||||
|
- Notifications are now sent out when flap detection is disabled on a host/service-specific
|
||||||
|
or program-wide basis ($NOTIFICATIONTYPE$ macro = "FLAPPINGDISABLED")
|
||||||
|
- Notifications can now be sent out when scheduled downtime starts, ends, and is cancelled. The
|
||||||
|
$NOTIFICATIONTYPE$ macro will be set to "DOWNTIMESTART", "DOWNTIMEEND", or "DOWNTIMECANCELLED",
|
||||||
|
respectively. In order to receive downtime notifications, specify 's' or 'downtime' in contact, host,
|
||||||
|
and/or service notification options.
|
||||||
|
|
||||||
|
* Object changes:
|
||||||
|
- Added ability to use multiple template names (separated by commas) in object definitions
|
||||||
|
- Added ability to null out optional character directives in object definitions (using 'null' without quotes)
|
||||||
|
- Added hostg/service/contactgroup_members directives to host/service/contactgroup definitions,
|
||||||
|
respectively, for allowing including host, service, or contact members from "sub" groups.
|
||||||
|
- Added support for custom variables in host, service, and contact definitions
|
||||||
|
- Added host_notifications_enabled, service_notifications_enabled, can_submit_commands to contact definitions
|
||||||
|
- Added optional display_name directive to host and service definitions
|
||||||
|
- Removed serviceextinfo definitions and merged variables with service definitions
|
||||||
|
- Removed hostextinfo definitions and merged variables with host definitions
|
||||||
|
- Services inherit contactgroups, notification interval, and notification period from associated host if not specified
|
||||||
|
- Service escalations inherit contactgroups, notification interval, and escalation period from associated service if not specified
|
||||||
|
- Host escalations inherit contactgroups, notification interval, and escalation period from associated host if not specified
|
||||||
|
- Host, service, host escalation, and service escalation definitions now support a 'contacts' directive, along with 'contact_groups'
|
||||||
|
- Service dependencies with blank dependent host/hostgroup names will create "same host" dependencies
|
||||||
|
|
||||||
|
|
||||||
|
* Performance optimizations:
|
||||||
|
- Added ability to precache object config files
|
||||||
|
- Added ability to exclude object relationship and circular path
|
||||||
|
checks from verification process
|
||||||
|
|
||||||
|
* Check output:
|
||||||
|
- Multiline output support for host and service checks
|
||||||
|
|
||||||
|
* Macro changes:
|
||||||
|
- Added $LONGHOSTOUTPUT$ and $LONGSERVICEOUTPUT$ macros
|
||||||
|
- Added $TEMPPATH$ macro
|
||||||
|
- Removed $COMMENTDATAFILE$ and $DOWNTIMEDATAFILE$ macros
|
||||||
|
- Added $HOSTDISPLAYNAME$ and $SERVICEDISPLAYNAME$ macros
|
||||||
|
- Custom host/service/contact macros accessible via $_HOST<varname>$, $_SERVICE<varname>, or $_CONTACT<varname>$.
|
||||||
|
On-demand host/service macros for custom vars are working. Custom vars are also set as environment vars.
|
||||||
|
- On-demand service macros can contain and empty host name field. In this case, the name of the current host will be used.
|
||||||
|
- $HOSTNOTES$ and $SERVICENOTES$ macros may now contain macros themselves
|
||||||
|
|
||||||
|
* Flapping changes:
|
||||||
|
- Added flap_detection_options directive to host and service definitions to control which
|
||||||
|
states (i.e. OK, WARNING, UNKNOWN, and/or CRITICAL) are used in flap detection logic
|
||||||
|
- Percent state change and state history are now retained and recorded even when host/service
|
||||||
|
flap detection is disabled.
|
||||||
|
- Hosts and services are immediately check for flapping when flap detection is enabled program-wide.
|
||||||
|
- Hosts/services that are flapping when flap detection is disabled program-wide are now logged
|
||||||
|
|
||||||
|
* External command changes:
|
||||||
|
- Added PROCESS_FILE external command to allow processing of external commands found in
|
||||||
|
an external (regular) file. Very useful for passive checks with long output or scripting.
|
||||||
|
- Custom commands can now be submitted to Nagios. Custom command names are prefixed with an underscore
|
||||||
|
and are not processed internally by the Nagios daemon. They may, however, be processed by NEB modules.
|
||||||
|
- External commands are now checked by default. Nagios 2.x and earlier did not check for external commands
|
||||||
|
by default.
|
||||||
|
|
||||||
|
* Status data changes:
|
||||||
|
- Contact status information is now saved (although it is not processed by the old CGIs)
|
||||||
|
|
||||||
|
* Retention data changes:
|
||||||
|
- Contact status information is now retained across program restarts
|
||||||
|
- Comment and downtime IDs are now stored across program restarts, should be unique unless reset
|
||||||
|
- Added retained_host/service_attribute_mask variables to control what host/service attribs are retained globally
|
||||||
|
- Added retained_process_host/service_attribute_mask variables to control what process attribs are retained
|
||||||
|
- Added retained_contact_host/service_attribute_mask variables to control what contact attribs are retained globally
|
||||||
|
|
||||||
|
* Downtime changes:
|
||||||
|
- Scheduled downtime entries are now stored in the status and retention files
|
||||||
|
|
||||||
|
* Comment changes:
|
||||||
|
- Comments are now stored in the status and retention files
|
||||||
|
- Non-persistent acknowledgement comments are now deleted when the acknowledgement is removed (instead of when Nagios restarts)
|
||||||
|
|
||||||
|
* Host check logic changes:
|
||||||
|
- Most host checks are now run asynchronously, in parallel!
|
||||||
|
- Scheduled host checks now help improve performance, instead of hinder it (if caching is enabled)
|
||||||
|
- Added cached_host_check_horizon option for enabling use of cached host check results
|
||||||
|
- Added enable_predictive_host_dependency_checks for enabling predictive checks of dependent hosts
|
||||||
|
- Added retry_interval to host definitions
|
||||||
|
- Added check_for_orphaned_hosts option and support for orphaned host checks
|
||||||
|
- Passive host check states can now be translated from their original DOWN/UNREACHABLE state if the
|
||||||
|
new translate_passive_host_results option is enabled
|
||||||
|
|
||||||
|
* Service check logic changes:
|
||||||
|
- 'parallelize' option in service definitions deprecated/no longer used
|
||||||
|
- Added cached_service_check_horizon option for enabling use of cached service check results
|
||||||
|
- Added enable_predictive_service_dependency_checks for enabling predictive checks of dependent services
|
||||||
|
|
||||||
|
* Dependency changes:
|
||||||
|
- Host and service dependencies can now have a timeperiod during which they're valid (dependency_period directive)
|
||||||
|
|
||||||
|
* Event broker changes:
|
||||||
|
- Updated NEB API version
|
||||||
|
- Modified adaptive program status callback
|
||||||
|
- Added adaptive contact status callback
|
||||||
|
- Added host/service precheck callbacks to allow modules to cancel/override internal host/service checks
|
||||||
|
|
||||||
|
* Embedded Perl changes:
|
||||||
|
- Added 'enable_embedded_perl' option to main config file to control whether epn is enabled/disabled
|
||||||
|
- Added support for perl plugins to specify whether or not they should be run under the epn... The
|
||||||
|
second to tenth line of a perl plugin may start with '# nagios: +epn' or '# nagios: -epn' to explicity indicate that it
|
||||||
|
should be run under the epn.
|
||||||
|
- Added 'use_embedded_perl_implicitly' option to main config file to determine whether or not perl
|
||||||
|
plugins will use the epn if they don't explicitly allow/disalow it
|
||||||
|
|
||||||
|
* CGI changes:
|
||||||
|
- Hostgroup and servicegroup summaries now show important/unimportant problem breakdowns like the TAC CGI
|
||||||
|
- Minor layout changes to host and service detail views in extinfo CGI
|
||||||
|
|
||||||
|
* Misc changes:
|
||||||
|
- More information given when testing scheduling (-s command line option)
|
||||||
|
- Removed fixed length restrictions for host names and service descriptions
|
||||||
|
- Plugin output length restriction bumped up to 4K
|
||||||
|
- Added temp_path directive to main config file for specifying temp directory
|
||||||
|
- Multiline output support for system commands via my_system()
|
||||||
|
- Added global event_id and notification_id vars that are at least unique during a single run of Nagios
|
||||||
|
- Default is now to check for orphaned services, rather than not
|
||||||
|
- Renamed service_reaper_frequency to check_result_reaper_frequency
|
||||||
|
- Fractional notification and check intervals are now supported (e.g. "3.5" minutes)
|
||||||
|
- Backslash chars are now used to escape command arguments that contain \ or ! characters
|
||||||
|
- Added 'external_command_buffer_slots' and 'check_result_buffer_slots' variables to specify size of internal buffers
|
||||||
|
- Added check statistics to status file, available via nagiostats for graphing in MRTG
|
||||||
|
- Added $HOSTGROUPNAMES$, $SERVICEGROUPNAMES$, $HOSTACKAUTHORNAME$, $HOSTACKAUTHORALIAS$, $SERVICEACKAUTHORNAME$,
|
||||||
|
and $SERVICEACKAUTHORALIAS$ macros
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
17
INSTALLING
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Nagios Installation Instructions
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
A quickstart installation guide can now be found in the HTML
|
||||||
|
documentation. You can find the quickstart guide (quickstart.html)
|
||||||
|
in the following subdirectory:
|
||||||
|
|
||||||
|
html/docs/
|
||||||
|
|
||||||
|
The quickstart covers all the basic steps you need to follow
|
||||||
|
to install Nagios, the Nagios plugins, and start out monitoring
|
||||||
|
the machine that Nagios is installed on.
|
||||||
|
|
||||||
|
Good luck!
|
||||||
|
|
||||||
|
|
||||||
|
|
11
LEGAL
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
All source code, binaries, documentation, information, and other files
|
||||||
|
contained in this distribution are provided AS IS with NO WARRANTY OF
|
||||||
|
ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY, AND FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
Nagios and the Nagios logo are trademarks, servicemarks, registered
|
||||||
|
trademarks or registered servicemarks owned by Nagios Enterprises, LLC.
|
||||||
|
All other trademarks, servicemarks, registered trademarks, and
|
||||||
|
registered servicemarks are the property of their respective owner(s).
|
||||||
|
|
340
LICENSE
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 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, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
379
Makefile.in
Normal file
@ -0,0 +1,379 @@
|
|||||||
|
###############################
|
||||||
|
# Makefile for Nagios
|
||||||
|
#
|
||||||
|
# Last Modified: 04-13-2008
|
||||||
|
###############################
|
||||||
|
|
||||||
|
|
||||||
|
# Source code directories
|
||||||
|
SRC_BASE=@srcdir@/base
|
||||||
|
SRC_CGI=@srcdir@/cgi
|
||||||
|
SRC_HTM=@srcdir@/html
|
||||||
|
SRC_MODULE=@srcdir@/module
|
||||||
|
SRC_INCLUDE=@srcdir@/include
|
||||||
|
SRC_COMMON=@srcdir@/common
|
||||||
|
SRC_XDATA=@srcdir@/xdata
|
||||||
|
SRC_CONTRIB=@srcdir@/contrib
|
||||||
|
SRC_TTAP=@srcdir@/t-tap
|
||||||
|
|
||||||
|
CC=@CC@
|
||||||
|
CFLAGS=@CFLAGS@ @DEFS@
|
||||||
|
LDFLAGS=@LDFLAGS@ @LIBS@
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
LOGDIR=@localstatedir@
|
||||||
|
CHECKRESULTDIR=@CHECKRESULTDIR@
|
||||||
|
CFGDIR=@sysconfdir@
|
||||||
|
BINDIR=@bindir@
|
||||||
|
CGIDIR=@sbindir@
|
||||||
|
LIBEXECDIR=@libexecdir@
|
||||||
|
HTMLDIR=@datadir@
|
||||||
|
INSTALL=@INSTALL@
|
||||||
|
INSTALL_OPTS=@INSTALL_OPTS@
|
||||||
|
COMMAND_OPTS=@COMMAND_OPTS@
|
||||||
|
HTTPD_CONF=@HTTPD_CONF@
|
||||||
|
INIT_DIR=@init_dir@
|
||||||
|
INIT_OPTS=-o root -g root
|
||||||
|
CGICFGDIR=$(CGIDIR)
|
||||||
|
PERLDIR=@PERLDIR@
|
||||||
|
|
||||||
|
USE_EVENTBROKER=@USE_EVENTBROKER@
|
||||||
|
USE_LIBTAP=@USE_LIBTAP@
|
||||||
|
|
||||||
|
INSTALLPERLSTUFF=@INSTALLPERLSTUFF@
|
||||||
|
|
||||||
|
CGIEXTRAS=@CGIEXTRAS@
|
||||||
|
|
||||||
|
SNPRINTF_O=@SNPRINTF_O@
|
||||||
|
|
||||||
|
CP=@CP@
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
none:
|
||||||
|
@echo "Please supply a command line argument (i.e. 'make all'). Other targets are:"
|
||||||
|
@echo " nagios cgis contrib modules"
|
||||||
|
@echo " clean"
|
||||||
|
@echo " install install-base install-cgis install-html install-exfoliation install-config install-init install-commandmode fullinstall"
|
||||||
|
# @echo " uninstall"
|
||||||
|
|
||||||
|
# FreeBSD make does not support -C option, so we'll use the Apache style... (patch by Stanley Hopcroft 12/27/1999)
|
||||||
|
|
||||||
|
pretty: indent
|
||||||
|
|
||||||
|
indent:
|
||||||
|
@sh indent-all.sh
|
||||||
|
|
||||||
|
ctags:
|
||||||
|
ctags -R
|
||||||
|
|
||||||
|
all:
|
||||||
|
cd $(SRC_BASE) && $(MAKE)
|
||||||
|
cd $(SRC_CGI) && $(MAKE)
|
||||||
|
cd $(SRC_HTM) && $(MAKE)
|
||||||
|
if [ x$(USE_EVENTBROKER) = xyes ]; then \
|
||||||
|
cd $(SRC_MODULE) && $(MAKE); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Compile finished ***"
|
||||||
|
@echo ""
|
||||||
|
@echo "If the main program and CGIs compiled without any errors, you"
|
||||||
|
@echo "can continue with installing Nagios as follows (type 'make'"
|
||||||
|
@echo "without any arguments for a list of all possible options):"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install"
|
||||||
|
@echo " - This installs the main program, CGIs, and HTML files"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-init"
|
||||||
|
@echo " - This installs the init script in $(DESTDIR)$(INIT_DIR)"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-commandmode"
|
||||||
|
@echo " - This installs and configures permissions on the"
|
||||||
|
@echo " directory for holding the external command file"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-config"
|
||||||
|
@echo " - This installs *SAMPLE* config files in $(DESTDIR)$(CFGDIR)"
|
||||||
|
@echo " You'll have to modify these sample files before you can"
|
||||||
|
@echo " use Nagios. Read the HTML documentation for more info"
|
||||||
|
@echo " on doing this. Pay particular attention to the docs on"
|
||||||
|
@echo " object configuration files, as they determine what/how"
|
||||||
|
@echo " things get monitored!"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-webconf"
|
||||||
|
@echo " - This installs the Apache config file for the Nagios"
|
||||||
|
@echo " web interface"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-exfoliation"
|
||||||
|
@echo " - This installs the Exfoliation theme for the Nagios"
|
||||||
|
@echo " web interface"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-classicui"
|
||||||
|
@echo " - This installs the classic theme for the Nagios"
|
||||||
|
@echo " web interface"
|
||||||
|
@echo ""
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Support Notes *******************************************"
|
||||||
|
@echo ""
|
||||||
|
@echo "If you have questions about configuring or running Nagios,"
|
||||||
|
@echo "please make sure that you:"
|
||||||
|
@echo ""
|
||||||
|
@echo " - Look at the sample config files"
|
||||||
|
@echo " - Read the documentation on the Nagios Library at:"
|
||||||
|
@echo " http://library.nagios.com"
|
||||||
|
@echo ""
|
||||||
|
@echo "before you post a question to one of the mailing lists."
|
||||||
|
@echo "Also make sure to include pertinent information that could"
|
||||||
|
@echo "help others help you. This might include:"
|
||||||
|
@echo ""
|
||||||
|
@echo " - What version of Nagios you are using"
|
||||||
|
@echo " - What version of the plugins you are using"
|
||||||
|
@echo " - Relevant snippets from your config files"
|
||||||
|
@echo " - Relevant error messages from the Nagios log file"
|
||||||
|
@echo ""
|
||||||
|
@echo "For more information on obtaining support for Nagios, visit:"
|
||||||
|
@echo ""
|
||||||
|
@echo " http://support.nagios.com"
|
||||||
|
@echo ""
|
||||||
|
@echo "*************************************************************"
|
||||||
|
@echo ""
|
||||||
|
@echo "Enjoy."
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
nagios:
|
||||||
|
cd $(SRC_BASE) && $(MAKE)
|
||||||
|
|
||||||
|
config:
|
||||||
|
@echo "Sample config files are automatically generated once you run the"
|
||||||
|
@echo "configure script. You can install the sample config files on your"
|
||||||
|
@echo "system by using the 'make install-config' command."
|
||||||
|
|
||||||
|
cgis:
|
||||||
|
cd $(SRC_CGI) && $(MAKE)
|
||||||
|
|
||||||
|
html:
|
||||||
|
cd $(SRC_HTM) && $(MAKE)
|
||||||
|
|
||||||
|
contrib:
|
||||||
|
cd $(SRC_CONTRIB) && $(MAKE)
|
||||||
|
|
||||||
|
modules:
|
||||||
|
cd $(SRC_MODULE) && $(MAKE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
cd $(SRC_BASE) && $(MAKE) $@
|
||||||
|
cd $(SRC_CGI) && $(MAKE) $@
|
||||||
|
cd $(SRC_COMMON) && $(MAKE) $@
|
||||||
|
cd $(SRC_XDATA) && $(MAKE) $@
|
||||||
|
cd $(SRC_HTM) && $(MAKE) $@
|
||||||
|
cd $(SRC_INCLUDE) && $(MAKE) $@
|
||||||
|
cd $(SRC_CONTRIB) && $(MAKE) $@
|
||||||
|
cd $(SRC_MODULE) && $(MAKE) $@
|
||||||
|
cd $(SRC_TTAP) && $(MAKE) $@
|
||||||
|
rm -f *.cfg core
|
||||||
|
rm -f *~ *.*~ */*~ */*.*~ */*/*.*~
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
cd $(SRC_BASE) && $(MAKE) $@
|
||||||
|
cd $(SRC_CGI) && $(MAKE) $@
|
||||||
|
cd $(SRC_COMMON) && $(MAKE) $@
|
||||||
|
cd $(SRC_XDATA) && $(MAKE) $@
|
||||||
|
cd $(SRC_HTM) && $(MAKE) $@
|
||||||
|
cd $(SRC_INCLUDE) && $(MAKE) $@
|
||||||
|
cd $(SRC_CONTRIB) && $(MAKE) $@
|
||||||
|
cd $(SRC_MODULE) && $(MAKE) $@
|
||||||
|
cd $(SRC_TTAP) && $(MAKE) $@
|
||||||
|
rm -f sample-config/*.cfg sample-config/*.conf sample-config/template-object/*.cfg
|
||||||
|
rm -f daemon-init pkginfo
|
||||||
|
rm -f Makefile subst
|
||||||
|
rm -f config.log config.status config.cache
|
||||||
|
rm -f tags
|
||||||
|
|
||||||
|
devclean: distclean
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(MAKE) test-perl
|
||||||
|
$(MAKE) test-tap
|
||||||
|
|
||||||
|
test-tap: tap/src/tap.o nagios cgis
|
||||||
|
@if [ x$(USE_LIBTAP) = xyes ]; then \
|
||||||
|
cd $(SRC_TTAP) && $(MAKE) test; \
|
||||||
|
else \
|
||||||
|
echo "NOTE: You must run configure with --enable-libtap to run the C tap tests"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
tap/src/tap.o:
|
||||||
|
cd tap && $(MAKE)
|
||||||
|
|
||||||
|
test-perl: cgis
|
||||||
|
cd t && $(MAKE) test
|
||||||
|
|
||||||
|
install-html:
|
||||||
|
cd $(SRC_HTM) && $(MAKE) install
|
||||||
|
make install-exfoliation
|
||||||
|
|
||||||
|
install-base:
|
||||||
|
cd $(SRC_BASE) && $(MAKE) install
|
||||||
|
|
||||||
|
install-cgis:
|
||||||
|
cd $(SRC_CGI) && $(MAKE) install
|
||||||
|
|
||||||
|
install:
|
||||||
|
cd $(SRC_BASE) && $(MAKE) $@
|
||||||
|
cd $(SRC_CGI) && $(MAKE) $@
|
||||||
|
cd $(SRC_HTM) && $(MAKE) $@
|
||||||
|
$(MAKE) install-exfoliation
|
||||||
|
$(MAKE) install-basic
|
||||||
|
|
||||||
|
install-unstripped:
|
||||||
|
cd $(SRC_BASE) && $(MAKE) $@
|
||||||
|
cd $(SRC_CGI) && $(MAKE) $@
|
||||||
|
cd $(SRC_HTM) && $(MAKE) $@
|
||||||
|
$(MAKE) install-exfoliation
|
||||||
|
$(MAKE) install-basic
|
||||||
|
|
||||||
|
install-basic:
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBEXECDIR)
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)/archives
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CHECKRESULTDIR)
|
||||||
|
if [ $(INSTALLPERLSTUFF) = yes ]; then \
|
||||||
|
$(INSTALL) -m 664 $(INSTALL_OPTS) p1.pl $(DESTDIR)$(BINDIR); \
|
||||||
|
fi;
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Main program, CGIs and HTML files installed ***"
|
||||||
|
@echo ""
|
||||||
|
@echo "You can continue with installing Nagios as follows (type 'make'"
|
||||||
|
@echo "without any arguments for a list of all possible options):"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-init"
|
||||||
|
@echo " - This installs the init script in $(DESTDIR)$(INIT_DIR)"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-commandmode"
|
||||||
|
@echo " - This installs and configures permissions on the"
|
||||||
|
@echo " directory for holding the external command file"
|
||||||
|
@echo ""
|
||||||
|
@echo " make install-config"
|
||||||
|
@echo " - This installs sample config files in $(DESTDIR)$(CFGDIR)"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
|
||||||
|
install-config:
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CFGDIR)
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CFGDIR)/objects
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/nagios.cfg $(DESTDIR)$(CFGDIR)/nagios.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/cgi.cfg $(DESTDIR)$(CFGDIR)/cgi.cfg
|
||||||
|
$(INSTALL) -b -m 660 $(INSTALL_OPTS) sample-config/resource.cfg $(DESTDIR)$(CFGDIR)/resource.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/templates.cfg $(DESTDIR)$(CFGDIR)/objects/templates.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/commands.cfg $(DESTDIR)$(CFGDIR)/objects/commands.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/contacts.cfg $(DESTDIR)$(CFGDIR)/objects/contacts.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/timeperiods.cfg $(DESTDIR)$(CFGDIR)/objects/timeperiods.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/localhost.cfg $(DESTDIR)$(CFGDIR)/objects/localhost.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/windows.cfg $(DESTDIR)$(CFGDIR)/objects/windows.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/printer.cfg $(DESTDIR)$(CFGDIR)/objects/printer.cfg
|
||||||
|
$(INSTALL) -b -m 664 $(INSTALL_OPTS) sample-config/template-object/switch.cfg $(DESTDIR)$(CFGDIR)/objects/switch.cfg
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Config files installed ***"
|
||||||
|
@echo ""
|
||||||
|
@echo "Remember, these are *SAMPLE* config files. You'll need to read"
|
||||||
|
@echo "the documentation for more information on how to actually define"
|
||||||
|
@echo "services, hosts, etc. to fit your particular needs."
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
install-webconf:
|
||||||
|
$(INSTALL) -m 644 sample-config/httpd.conf $(DESTDIR)$(HTTPD_CONF)/nagios.conf
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Nagios/Apache conf file installed ***"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
install-exfoliation:
|
||||||
|
cp -rf contrib/exfoliation/stylesheets/* $(DESTDIR)$(HTMLDIR)/stylesheets
|
||||||
|
cp -rf contrib/exfoliation/images/* $(DESTDIR)$(HTMLDIR)/images
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Exfoliation theme installed ***"
|
||||||
|
@echo "NOTE: Use 'make install-classicui' to revert to classic Nagios theme";
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
install-classicui:
|
||||||
|
cp -rf html/stylesheets/* $(DESTDIR)$(HTMLDIR)/stylesheets
|
||||||
|
cp -rf html/images/* $(DESTDIR)$(HTMLDIR)/images
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Classic theme installed ***"
|
||||||
|
@echo "NOTE: Use 'make install-exfoliation' to use new Nagios theme";
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
install-init: install-daemoninit
|
||||||
|
|
||||||
|
install-daemoninit:
|
||||||
|
$(INSTALL) -m 755 -d $(INIT_OPTS) $(DESTDIR)$(INIT_DIR)
|
||||||
|
$(INSTALL) -m 755 $(INIT_OPTS) daemon-init $(DESTDIR)$(INIT_DIR)/nagios
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** Init script installed ***"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
|
||||||
|
install-commandmode:
|
||||||
|
$(INSTALL) -m 775 $(COMMAND_OPTS) -d $(DESTDIR)$(LOGDIR)/rw
|
||||||
|
chmod g+s $(DESTDIR)$(LOGDIR)/rw
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "*** External command directory configured ***"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
|
||||||
|
fullinstall: install install-init install-commandmode install-webconf
|
||||||
|
|
||||||
|
# Uninstall is too destructive if base install directory is /usr, etc.
|
||||||
|
#uninstall:
|
||||||
|
# rm -rf $(DESTDIR)$(BINDIR)/nagios $(DESTDIR)$(CGIDIR)/*.cgi $(DESTDIR)$(CFGDIR)/*.cfg $(DESTDIR)$(HTMLDIR)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Targets for creating packages on various architectures
|
||||||
|
#
|
||||||
|
|
||||||
|
# Solaris pkgmk
|
||||||
|
PACKDIR=@PACKDIR@
|
||||||
|
VERSION=@VERSION@
|
||||||
|
|
||||||
|
Prototype:
|
||||||
|
if [ ! -d $(PACKDIR) ] ; then mkdir $(PACKDIR); fi
|
||||||
|
if [ ! -d $(PACKDIR)/etc ] ; then mkdir $(PACKDIR)/etc; fi
|
||||||
|
if [ ! -d $(PACKDIR)/etc/init.d ] ; then mkdir $(PACKDIR)/etc/init.d; fi
|
||||||
|
if [ ! -d $(PACKDIR)/etc/nagios ] ; then mkdir $(PACKDIR)/etc/nagios; fi
|
||||||
|
$(MAKE) all
|
||||||
|
$(MAKE) DESTDIR=$(PACKDIR) INIT_OPTS='' INSTALL_OPTS='' COMMAND_OPTS='' nagios_grp='' nagios_usr='' fullinstall
|
||||||
|
$(INSTALL) -m 644 sample-config/nagios.cfg $(PACKDIR)$(CFGDIR)/nagios.cfg.$(VERSION)
|
||||||
|
$(INSTALL) -m 644 sample-config/cgi.cfg $(PACKDIR)$(CFGDIR)/cgi.cfg.$(VERSION)
|
||||||
|
$(INSTALL) -m 640 sample-config/resource.cfg $(PACKDIR)$(CFGDIR)/resource.cfg.$(VERSION)
|
||||||
|
$(INSTALL) -m 664 sample-config/template-object/bigger.cfg $(PACKDIR)$(CFGDIR)/bigger.cfg.$(VERSION)
|
||||||
|
$(INSTALL) -m 664 sample-config/template-object/minimal.cfg $(PACKDIR)$(CFGDIR)/minimal.cfg.$(VERSION)
|
||||||
|
$(INSTALL) -m 664 sample-config/template-object/checkcommands.cfg $(PACKDIR)$(CFGDIR)/checkcommands.cfg.$(VERSION)
|
||||||
|
$(INSTALL) -m 664 sample-config/template-object/misccommands.cfg $(PACKDIR)$(CFGDIR)/misccommands.cfg.$(VERSION)
|
||||||
|
cd contrib; $(MAKE) all; $(MAKE) DESTDIR=$(PACKDIR) INIT_OPTS='' INSTALL_OPTS='' COMMAND_OPTS='' nagios_grp='' nagios_usr='' install
|
||||||
|
echo i pkginfo> Prototype
|
||||||
|
if [ -f checkinstall ] ; then echo i checkinstall>> Prototype; fi
|
||||||
|
if [ -f preinstall ] ; then echo i preinstall>> Prototype; fi
|
||||||
|
if [ -f postinstall ] ; then echo i postinstall>> Prototype; fi
|
||||||
|
pkgproto $(PACKDIR)=/ | sed -e "s|$(LOGNAME) $(GROUP)$$|root root|" | egrep -v "(s|d) none (/|/etc|/var|/usr|/usr/local) " >> Prototype
|
||||||
|
|
||||||
|
pkg/nagios/pkgmap: Prototype
|
||||||
|
mkdir $(PACKDIR)/nagios
|
||||||
|
pkgmk -o -r / -f Prototype -d $(PACKDIR) nagios
|
||||||
|
|
||||||
|
nagios.SPARC.pkg.tar.gz: pkg/nagios/pkgmap
|
||||||
|
cd $(PACKDIR) && tar -cf - nagios | gzip -9 -c > ../nagios.SPARC.pkg.tar.gz
|
||||||
|
|
||||||
|
pkgset: nagios.SPARC.pkg.tar.gz
|
||||||
|
|
||||||
|
pkgclean:
|
||||||
|
rm -rf pkg Prototype nagios.SPARC.pkg.tar.gz
|
||||||
|
|
||||||
|
# Targets that always get built
|
||||||
|
.PHONY: indent clean clean distclean
|
39
OutputTrap.pm
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package OutputTrap;
|
||||||
|
#
|
||||||
|
# Methods for use by tied STDOUT in embedded PERL module.
|
||||||
|
#
|
||||||
|
# Simply redirects STDOUT to a temporary file associated with the
|
||||||
|
# current child/grandchild process.
|
||||||
|
#
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
# Perl before 5.6 does not seem to have warnings.pm ???
|
||||||
|
#use warnings;
|
||||||
|
use IO::File;
|
||||||
|
|
||||||
|
sub TIEHANDLE {
|
||||||
|
my ($class, $fn) = @_;
|
||||||
|
my $handle = new IO::File "> $fn" or die "Cannot open embedded work filei $!\n";
|
||||||
|
bless { FH => $handle, Value => 0}, $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub PRINT {
|
||||||
|
my $self = shift;
|
||||||
|
my $handle = $self -> {FH};
|
||||||
|
print $handle join("",@_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub PRINTF {
|
||||||
|
my $self = shift;
|
||||||
|
my $fmt = shift;
|
||||||
|
my $handle = $self -> {FH};
|
||||||
|
printf $handle ($fmt,@_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub CLOSE {
|
||||||
|
my $self = shift;
|
||||||
|
my $handle = $self -> {FH};
|
||||||
|
close $handle;
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
__END__
|
29
README
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Nagios 3.x README
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
|
||||||
|
Nagios is a host/service/network monitoring program written in C and
|
||||||
|
released under the GNU General Public License. CGI programs are
|
||||||
|
included to allow you to view the current status, history, etc via
|
||||||
|
a web interface if you so desire.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
1) Monitoring of network services (via SMTP, POP3, HTTP, PING, etc).
|
||||||
|
2) A plugin interface to allow for user-developed service monitoring methods.
|
||||||
|
3) Notifications when problems occur and get resolved (via email, pager,
|
||||||
|
or user-defined method).
|
||||||
|
4) Ability to define "event handlers" for proactive problem resolution
|
||||||
|
5) Web output (current status, notifications, problem history, log file, etc.)
|
||||||
|
6) Automatic log file rotation/archiving
|
||||||
|
|
||||||
|
For installation instructions, use a web browser to read the HTML documentation
|
||||||
|
in the html/docs subdirectory.
|
||||||
|
|
||||||
|
Visit the Nagios homepage at http://www.nagios.org for online
|
||||||
|
documentation, new releases, bug reports, information on the mailing
|
||||||
|
lists, etc.
|
||||||
|
|
||||||
|
-- Ethan Galstad (egalstad@nagios.org)
|
||||||
|
|
||||||
|
|
303
THANKS
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
=======
|
||||||
|
THANKS!
|
||||||
|
=======
|
||||||
|
|
||||||
|
The success of Nagios has been due to the fantastic community members that
|
||||||
|
support it and provide bug reports, patches, and great ideas. Here are a
|
||||||
|
few of the many members that have contributed to Nagios in various ways
|
||||||
|
since 1999. If I missed your name, let me know.
|
||||||
|
|
||||||
|
* Greg Abrams
|
||||||
|
* Petr Adamec
|
||||||
|
* Gavin Adams
|
||||||
|
* David Allan
|
||||||
|
* Felipe Almeida
|
||||||
|
* Markus Almroth
|
||||||
|
* Jon Andrews
|
||||||
|
* Michael Anthon
|
||||||
|
* Bernd Arnold
|
||||||
|
* Erwan Arzur
|
||||||
|
* Volker Aust
|
||||||
|
* Hendrik Baecker
|
||||||
|
* Markus Baertschi
|
||||||
|
* Michael Bailey
|
||||||
|
* Luigi Balzano
|
||||||
|
* Sebastien Barbereau
|
||||||
|
* Wolfgang Barth
|
||||||
|
* Devin Bayer
|
||||||
|
* Simon Beale
|
||||||
|
* Ben Bell
|
||||||
|
* Marlo Bell
|
||||||
|
* Ray Bengen
|
||||||
|
* Derrick Bennett
|
||||||
|
* Chris Bensend
|
||||||
|
* Kevin Benton
|
||||||
|
* Gary Berger
|
||||||
|
* Sven-Göran Bergh
|
||||||
|
* Jochen Bern
|
||||||
|
* Tom Bertelson
|
||||||
|
* Joel Berry
|
||||||
|
* Olivier Beytrison
|
||||||
|
* Christoph Biedl
|
||||||
|
* Dennis Biringer
|
||||||
|
* Mike Bird
|
||||||
|
* Jason Blakey
|
||||||
|
* Jeffrey Blank
|
||||||
|
* Ian Blenke
|
||||||
|
* Fran Boon
|
||||||
|
* Jeremy Bouse
|
||||||
|
* Adam Bowen
|
||||||
|
* Ludo Bosmans
|
||||||
|
* Henning Brauer
|
||||||
|
* Michael Bunk
|
||||||
|
* Daniel Burke
|
||||||
|
* Grant Byers
|
||||||
|
* John Calcote
|
||||||
|
* Don Carroll
|
||||||
|
* Ian Cass
|
||||||
|
* Alexios Chouhoulas
|
||||||
|
* Allan Clark
|
||||||
|
* Jonathan Clarke
|
||||||
|
* Justin Clarke
|
||||||
|
* Perry Clarke
|
||||||
|
* Nick Cleaton
|
||||||
|
* Charlie Cook
|
||||||
|
* Garry Cook
|
||||||
|
* Jeff Cours
|
||||||
|
* Michelle Craft
|
||||||
|
* Matthias Cramer
|
||||||
|
* Matthieu Kermagoret
|
||||||
|
* Jim Crilley
|
||||||
|
* Joel Crisp
|
||||||
|
* Jean-Eric Cuendet
|
||||||
|
* Ahmon Dancy
|
||||||
|
* Jan David
|
||||||
|
* Stephen Davies
|
||||||
|
* Karl DeBisschop
|
||||||
|
* Tom De Blende
|
||||||
|
* Mark DeTrano
|
||||||
|
* Thomas Dohl
|
||||||
|
* Mike Dorman
|
||||||
|
* Albrecht Dress
|
||||||
|
* Alok Dubey
|
||||||
|
* Jim Dumser
|
||||||
|
* Thomas Dunkel
|
||||||
|
* Matthias Eble
|
||||||
|
* Ari Edelkind
|
||||||
|
* Matthias Eichler
|
||||||
|
* Rob Enders
|
||||||
|
* Andreas Ericsson
|
||||||
|
* Matt Ezell
|
||||||
|
* Sylvain Falardeau
|
||||||
|
* Duncan Ferguson
|
||||||
|
* Sean Finney
|
||||||
|
* Andy Finkenstadt
|
||||||
|
* Mika Fischer
|
||||||
|
* Matthias Flacke
|
||||||
|
* Marcus Fleige
|
||||||
|
* Matthias Flittner
|
||||||
|
* Bastian Friedrich
|
||||||
|
* Jean Gabes
|
||||||
|
* Szabo Gabor
|
||||||
|
* Mathieu Gagne
|
||||||
|
* Dan Gailey
|
||||||
|
* Darren Gamble
|
||||||
|
* Robert Gash
|
||||||
|
* Hugo Gayosso
|
||||||
|
* Subhendu Ghosh
|
||||||
|
* Mark Goldfinch
|
||||||
|
* Jeffrey Goldschrafe
|
||||||
|
* Jan Grant
|
||||||
|
* Stephen Gran
|
||||||
|
* Matthew Grant
|
||||||
|
* Martin Green
|
||||||
|
* Todd Green
|
||||||
|
* Nathan Grennan
|
||||||
|
* Sebastian Guarino
|
||||||
|
* Thomas Guyot-Sionnest
|
||||||
|
* Sergio Guzman
|
||||||
|
* Hugo Hallqvist
|
||||||
|
* Lars Hansson
|
||||||
|
* Ben Heavner
|
||||||
|
* Lars Hecking
|
||||||
|
* Jason Hedden
|
||||||
|
* Karl Hegbloom
|
||||||
|
* Thomas Hepper
|
||||||
|
* Marcus Hildenbrand
|
||||||
|
* Arne Hinrichsen
|
||||||
|
* Ronald Ho
|
||||||
|
* Stanley Hopcroft
|
||||||
|
* Sam Howard
|
||||||
|
* Torsten Huebler
|
||||||
|
* Stig Jacobsen
|
||||||
|
* Percy Jahn
|
||||||
|
* Stewart James
|
||||||
|
* Olivier Jan
|
||||||
|
* Jeff Johnson
|
||||||
|
* Jonathan Kamens
|
||||||
|
* Andrew Kaplan
|
||||||
|
* Lars Kellogg-Stedman
|
||||||
|
* Paul Kent
|
||||||
|
* Matthieu Kermagoret
|
||||||
|
* Matthias Kerk
|
||||||
|
* Bo Kersey
|
||||||
|
* Andreas Kirchwitz
|
||||||
|
* Burkhard Klaus
|
||||||
|
* Tobias Klausmann
|
||||||
|
* Igno Kley
|
||||||
|
* Rene Klootwijk
|
||||||
|
* David Kmoch
|
||||||
|
* Brandon Knitter
|
||||||
|
* Uwe Knop
|
||||||
|
* Ryoji Kobayashi
|
||||||
|
* Uwe Knop
|
||||||
|
* Daniel Koffler
|
||||||
|
* Petya Kohts
|
||||||
|
* Chris Kolquist
|
||||||
|
* Jiri Kostern
|
||||||
|
* Christoph Kron
|
||||||
|
* Ivan Kuncl
|
||||||
|
* Dean Lane
|
||||||
|
* Ingo Lantschner
|
||||||
|
* Gerhard Lausser
|
||||||
|
* William Leibzon
|
||||||
|
* Pedro Leite
|
||||||
|
* Bernard Li
|
||||||
|
* Joerg Linge
|
||||||
|
* Michael Little
|
||||||
|
* Shad Lords
|
||||||
|
* Larry Low
|
||||||
|
* Michael Lubben
|
||||||
|
* Tyler Lund
|
||||||
|
* Jacob Lundqvist
|
||||||
|
* James Maddison
|
||||||
|
* Joseph Maiorana
|
||||||
|
* Ricardo Maraschini
|
||||||
|
* Michael Marineau
|
||||||
|
* Roberto Marrodan
|
||||||
|
* Ernst-Deiter Martin
|
||||||
|
* Christoph Maser
|
||||||
|
* Christian Masopust
|
||||||
|
* Emanuel Massano
|
||||||
|
* Richard Mayhew
|
||||||
|
* Mike McHenry
|
||||||
|
* Gordon Messmer
|
||||||
|
* Lars Michelson
|
||||||
|
* Martin Mielke
|
||||||
|
* Christian Mies
|
||||||
|
* Gary Miller
|
||||||
|
* Peter Valdemar Morch
|
||||||
|
* James Moseley
|
||||||
|
* Tobias Mucke
|
||||||
|
* Gerd Mueller
|
||||||
|
* Bob (Netshell)
|
||||||
|
* Time Niemueller
|
||||||
|
* Sven Nierlein
|
||||||
|
* Michael O'Reilly
|
||||||
|
* Tomer Okavi
|
||||||
|
* Vadim Okun
|
||||||
|
* Hiren Patel
|
||||||
|
* Rob Patrick
|
||||||
|
* Remi Paulmier
|
||||||
|
* Alex Peeters
|
||||||
|
* James "Showkilr" Peterson
|
||||||
|
* Cary Petterborg
|
||||||
|
* Bill Pier
|
||||||
|
* Badri Pillai
|
||||||
|
* Steven Pokrandt
|
||||||
|
* Jim Popovitch
|
||||||
|
* Janet Post
|
||||||
|
* Paul Pot
|
||||||
|
* Daniel Pouzzner
|
||||||
|
* Marc Powell
|
||||||
|
* William Preston
|
||||||
|
* Patrick Proy
|
||||||
|
* Luiz Felipe R E
|
||||||
|
* Alain Radix
|
||||||
|
* Kenneth Ray
|
||||||
|
* Nick Reinking
|
||||||
|
* Rob Remus
|
||||||
|
* Alessandro Ren
|
||||||
|
* Bob Rentschler
|
||||||
|
* Mindaugas Riauba
|
||||||
|
* Matthew Richardson
|
||||||
|
* Dietmar Rieder
|
||||||
|
* Brian Riggs
|
||||||
|
* Peter Ringe
|
||||||
|
* Eirik Robertstad
|
||||||
|
* Stefan Rompf
|
||||||
|
* Amir Rosenblatt
|
||||||
|
* Luke Ross
|
||||||
|
* Ralph Rossner
|
||||||
|
* Chris Rothecker
|
||||||
|
* John Rouillard
|
||||||
|
* Yves Rubin
|
||||||
|
* Mattias Ryrlen
|
||||||
|
* Jonathan Saggau
|
||||||
|
* Karel Salavec
|
||||||
|
* Jorge Sanchez
|
||||||
|
* Bogdan Sandu
|
||||||
|
* Pavel Satrapa
|
||||||
|
* Frederic Schaer
|
||||||
|
* Mark Schenker
|
||||||
|
* David Schlecht
|
||||||
|
* Russell Scibetti
|
||||||
|
* Max Schubert
|
||||||
|
* Stefan Schurtz
|
||||||
|
* Thomas Sebastien
|
||||||
|
* Brian Seklecki
|
||||||
|
* Denis Seleznyov
|
||||||
|
* Lonny Selinger
|
||||||
|
* Nate Shafer
|
||||||
|
* Moshe Sharon
|
||||||
|
* Andy Shellam
|
||||||
|
* Nick Shore
|
||||||
|
* Ryan Skorstad
|
||||||
|
* Michael Smedius
|
||||||
|
* Gordon Smith
|
||||||
|
* Lou Sneddon
|
||||||
|
* Mark Spieth
|
||||||
|
* Tim Starling
|
||||||
|
* Thomas Stolle
|
||||||
|
* Kevin Stone
|
||||||
|
* Herbert Straub
|
||||||
|
* Sven Strickroth
|
||||||
|
* SUSE Linux Team
|
||||||
|
* Horvath Tamas
|
||||||
|
* Nicholas Tang
|
||||||
|
* Glenn Thompson
|
||||||
|
* Robert Thompson
|
||||||
|
* Josh Thorstad
|
||||||
|
* David Tilloy
|
||||||
|
* Gennaro Tortone
|
||||||
|
* Steve Underwood
|
||||||
|
* Kai Ung
|
||||||
|
* Stephane Urbanovski
|
||||||
|
* Franky Van Liedekerke
|
||||||
|
* Nikola Vassilev
|
||||||
|
* Esteban Manchado Velazquez
|
||||||
|
* Geert Vanderkelen
|
||||||
|
* Carlos Velasco
|
||||||
|
* Jan Vejvalka
|
||||||
|
* Robert August Vincent II
|
||||||
|
* Dave Viner
|
||||||
|
* Ton Voon
|
||||||
|
* Lars Vogdt
|
||||||
|
* Phil Walther
|
||||||
|
* Jeremy Weatherford
|
||||||
|
* Holger Weiss
|
||||||
|
* Tom Welsh
|
||||||
|
* Brad Werschler
|
||||||
|
* Peter Westlake
|
||||||
|
* Todd Wheeler
|
||||||
|
* Florian Weimer
|
||||||
|
* Tim Wilde
|
||||||
|
* Chris Witterholt
|
||||||
|
* Evan Winter
|
||||||
|
* Armin Wolfermann
|
||||||
|
* Greg Woods
|
||||||
|
* Cliff Woolley
|
||||||
|
* Mitch Wright
|
||||||
|
* Michal Zimen
|
||||||
|
* Pawel Zuzelski
|
||||||
|
* Anders K. Lindgren
|
19
UPGRADING
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Upgrading to Nagios 3.x
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The HTML documentation covers what you need to know in order
|
||||||
|
to upgrade from Nagios 2.x You can find the documentation in
|
||||||
|
the following subdirectory:
|
||||||
|
|
||||||
|
html/docs
|
||||||
|
|
||||||
|
Make sure to read the following sections:
|
||||||
|
|
||||||
|
- "What's New" (whatsnew.html)
|
||||||
|
- "Upgrading Nagios" (upgrading.html)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
3
base/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.o
|
||||||
|
nagios
|
||||||
|
nagiostats
|
213
base/Makefile.in
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
############################
|
||||||
|
# Makefile for Nagios
|
||||||
|
#
|
||||||
|
# Last Modified: 12-05-2008
|
||||||
|
############################
|
||||||
|
|
||||||
|
|
||||||
|
# Source code directories
|
||||||
|
SRC_COMMON=../common
|
||||||
|
SRC_INCLUDE=../include
|
||||||
|
SRC_XDATA=../xdata
|
||||||
|
|
||||||
|
CC=@CC@
|
||||||
|
CFLAGS=-Wall @CFLAGS@ @DEFS@ -DNSCORE
|
||||||
|
|
||||||
|
# Compiler flags for use with gprof
|
||||||
|
#CFLAGS=-pg -DHAVE_CONFIG_H -DNSCORE
|
||||||
|
|
||||||
|
# Compiler flags for use with Valgrind
|
||||||
|
#CFLAGS=-O0 -g -DHAVE_CONFIG_H -DNSCORE
|
||||||
|
|
||||||
|
# Compiler flags for optimization (overrides default)
|
||||||
|
#CFLAGS=-O3 -Wall -fno-strict-aliasing -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -DHAVE_CONFIG_H -DNSCORE
|
||||||
|
|
||||||
|
# Compiler flags for optimization (complements default)
|
||||||
|
#CFLAGS_WARN=-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs
|
||||||
|
#CFLAGS_DEBUG=-ggdb3 -g3
|
||||||
|
#CFLAGS_GPROF=-pg
|
||||||
|
#CFLAGS+=$(CFLAGS_WARN) $(CFLAGS_DEBUG) $(CFLAGS_GPROF)
|
||||||
|
|
||||||
|
LDFLAGS=@LDFLAGS@
|
||||||
|
LIBS=@LIBS@
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
LOGDIR=@localstatedir@
|
||||||
|
CFGDIR=@sysconfdir@
|
||||||
|
BINDIR=@bindir@
|
||||||
|
CGIDIR=@sbindir@
|
||||||
|
HTMLDIR=@datarootdir@
|
||||||
|
INSTALL=@INSTALL@
|
||||||
|
INSTALL_OPTS=@INSTALL_OPTS@
|
||||||
|
COMMAND_OPTS=@COMMAND_OPTS@
|
||||||
|
STRIP=@STRIP@
|
||||||
|
|
||||||
|
CGIURL=@cgiurl@
|
||||||
|
HTMURL=@htmurl@
|
||||||
|
|
||||||
|
MATHLIBS=-lm
|
||||||
|
PERLLIBS=@PERLLIBS@
|
||||||
|
PERLXSI_O=@PERLXSI_O@
|
||||||
|
SOCKETLIBS=@SOCKETLIBS@
|
||||||
|
THREADLIBS=@THREADLIBS@
|
||||||
|
BROKERLIBS=@BROKERLIBS@
|
||||||
|
|
||||||
|
BROKER_LDFLAGS=@BROKER_LDFLAGS@
|
||||||
|
|
||||||
|
CP=@CP@
|
||||||
|
|
||||||
|
# External data I/O code and headers
|
||||||
|
XSDC=@XSDC@
|
||||||
|
XSDH=@XSDH@
|
||||||
|
XCDC=@XCDC@
|
||||||
|
XCDH=@XCDH@
|
||||||
|
XRDC=@XRDC@
|
||||||
|
XRDH=@XRDH@
|
||||||
|
XODC=@XODC@
|
||||||
|
XODH=@XODH@
|
||||||
|
XPDC=@XPDC@
|
||||||
|
XPDH=@XPDH@
|
||||||
|
XDDC=@XDDC@
|
||||||
|
XDDH=@XDDH@
|
||||||
|
|
||||||
|
# Extra base code
|
||||||
|
BASEEXTRALIBS=@BASEEXTRALIBS@
|
||||||
|
|
||||||
|
# Generated automatically from configure script
|
||||||
|
SNPRINTF_O=@SNPRINTF_O@
|
||||||
|
BROKER_O=@BROKER_O@
|
||||||
|
BROKER_H=@BROKER_H@
|
||||||
|
|
||||||
|
# Object data
|
||||||
|
#ODATALIBS=$(SRC_COMMON)/objects.c $(SRC_XDATA)/$(XODC)
|
||||||
|
#ODATAHDRS=$(SRC_INCLUDE)/objects.h $(SRC_XDATA)/$(XODH)
|
||||||
|
ODATALIBS=objects-base.o xobjects-base.o
|
||||||
|
ODATAHDRS=
|
||||||
|
ODATADEPS=$(ODATALIBS)
|
||||||
|
|
||||||
|
# Retention data
|
||||||
|
#RDATALIBS=sretention.o $(SRC_XDATA)/$(XRDC)
|
||||||
|
#RDATAHDRS=$(SRC_INCLUDE)/sretention.h $(SRC_XDATA)/$(XRDH)
|
||||||
|
RDATALIBS=retention-base.o xretention-base.o
|
||||||
|
RDATAHDRS=
|
||||||
|
RDATADEPS=$(RDATALIBS)
|
||||||
|
|
||||||
|
# Comment data
|
||||||
|
#CDATALIBS=$(SRC_COMMON)/comments.c $(SRC_XDATA)/$(XCDC)
|
||||||
|
#CDATAHDRS=$(SRC_INCLUDE)/comments.h $(SRC_XDATA)/$(XCDH)
|
||||||
|
CDATALIBS=comments-base.o xcomments-base.o
|
||||||
|
CDATAHDRS=
|
||||||
|
CDATADEPS=$(CDATALIBS)
|
||||||
|
|
||||||
|
# Status data
|
||||||
|
#SDATALIBS=$(SRC_COMMON)/statusdata.c $(SRC_XDATA)/$(XSDC)
|
||||||
|
#SDATAHDRS=$(SRC_INCLUDE)/statusdata.h $(SRC_XDATA)/$(XSDH)
|
||||||
|
SDATALIBS=statusdata-base.o xstatusdata-base.o
|
||||||
|
SDATAHDRS=
|
||||||
|
SDATADEPS=$(SDATALIBS)
|
||||||
|
|
||||||
|
# Performance data
|
||||||
|
#PDATALIBS=perfdata.o $(SRC_XDATA)/$(XPDC)
|
||||||
|
#PDATAHDRS=$(SRC_INCLUDE)/perfdata.h $(SRC_XDATA)/$(XPDH)
|
||||||
|
PDATALIBS=perfdata-base.o xperfdata-base.o
|
||||||
|
PDATAHDRS=
|
||||||
|
PDATADEPS=$(PDATALIBS)
|
||||||
|
|
||||||
|
# Downtime data
|
||||||
|
#DDATALIBS=$(SRC_COMMON)/downtime.c $(SRC_XDATA)/$(XDDC)
|
||||||
|
#DDATAHDRS=$(SRC_INCLUDE)/downtime.h $(SRC_XDATA)/$(XDDH)
|
||||||
|
DDATALIBS=downtime-base.o xdowntime-base.o
|
||||||
|
DDATAHDRS=
|
||||||
|
DDATADEPS=$(DDATALIBS)
|
||||||
|
|
||||||
|
|
||||||
|
OBJS=$(BROKER_O) $(SRC_COMMON)/shared.o checks.o config.o commands.o events.o flapping.o logging.o macros-base.o netutils.o notifications.o sehandlers.o skiplist.o utils.o $(RDATALIBS) $(CDATALIBS) $(ODATALIBS) $(SDATALIBS) $(PDATALIBS) $(DDATALIBS) $(BASEEXTRALIBS) $(SNPRINTF_O) $(PERLXSI_O)
|
||||||
|
OBJDEPS=$(ODATADEPS) $(ODATADEPS) $(RDATADEPS) $(CDATADEPS) $(SDATADEPS) $(PDATADEPS) $(DDATADEPS) $(BROKER_H)
|
||||||
|
|
||||||
|
all: nagios nagiostats
|
||||||
|
|
||||||
|
|
||||||
|
######## REQUIRED FILES ##########
|
||||||
|
|
||||||
|
macros-base.o: $(SRC_COMMON)/macros.c $(SRC_INCLUDE)/macros.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/macros.c
|
||||||
|
|
||||||
|
skiplist.o: $(SRC_COMMON)/skiplist.c $(SRC_INCLUDE)/skiplist.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/skiplist.c
|
||||||
|
|
||||||
|
objects-base.o: $(SRC_COMMON)/objects.c $(SRC_INCLUDE)/objects.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/objects.c
|
||||||
|
|
||||||
|
xobjects-base.o: $(SRC_XDATA)/$(XODC) $(SRC_XDATA)/$(XODH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XODC)
|
||||||
|
|
||||||
|
statusdata-base.o: $(SRC_COMMON)/statusdata.c $(SRC_INCLUDE)/statusdata.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/statusdata.c
|
||||||
|
|
||||||
|
xstatusdata-base.o: $(SRC_XDATA)/$(XSDC) $(SRC_XDATA)/$(XSDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XSDC)
|
||||||
|
|
||||||
|
comments-base.o: $(SRC_COMMON)/comments.c $(SRC_INCLUDE)/comments.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/comments.c
|
||||||
|
|
||||||
|
xcomments-base.o: $(SRC_XDATA)/$(XCDC) $(SRC_XDATA)/$(XCDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XCDC)
|
||||||
|
|
||||||
|
downtime-base.o: $(SRC_COMMON)/downtime.c $(SRC_INCLUDE)/downtime.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/downtime.c
|
||||||
|
|
||||||
|
xdowntime-base.o: $(SRC_XDATA)/$(XDDC) $(SRC_XDATA)/$(XDDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XDDC)
|
||||||
|
|
||||||
|
perfdata-base.o: perfdata.c $(SRC_INCLUDE)/perfdata.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ perfdata.c
|
||||||
|
|
||||||
|
xperfdata-base.o: $(SRC_XDATA)/$(XPDC) $(SRC_XDATA)/$(XPDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XPDC)
|
||||||
|
|
||||||
|
retention-base.o: sretention.c $(SRC_INCLUDE)/sretention.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ sretention.c
|
||||||
|
|
||||||
|
xretention-base.o: $(SRC_XDATA)/$(XRDC) $(SRC_XDATA)/$(XRDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XRDC)
|
||||||
|
|
||||||
|
$(SRC_COMMON)/shared.o: $(SRC_COMMON)/shared.c
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
|
########## NAGIOS ##########
|
||||||
|
|
||||||
|
nagios: nagios.c $(OBJS) $(OBJDEPS) $(SRC_INCLUDE)/nagios.h $(SRC_INCLUDE)/locations.h
|
||||||
|
$(CC) $(CFLAGS) -o $@ nagios.c $(OBJS) $(BROKER_LDFLAGS) $(LDFLAGS) $(PERLLIBS) $(MATHLIBS) $(SOCKETLIBS) $(THREADLIBS) $(BROKERLIBS) $(LIBS)
|
||||||
|
|
||||||
|
nagiostats: nagiostats.c $(SRC_INCLUDE)/locations.h
|
||||||
|
$(CC) $(CFLAGS) -o $@ nagiostats.c $(LDFLAGS) $(MATHLIBS) $(LIBS)
|
||||||
|
|
||||||
|
$(OBJS): $(SRC_INCLUDE)/locations.h
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f nagios nagiostats core *.o gmon.out
|
||||||
|
rm -f *~ *.*~
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f perlxsi.c
|
||||||
|
rm -f Makefile
|
||||||
|
|
||||||
|
devclean: distclean
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(MAKE) install-basic
|
||||||
|
$(MAKE) strip-post-install
|
||||||
|
|
||||||
|
install-unstripped:
|
||||||
|
$(MAKE) install-basic
|
||||||
|
|
||||||
|
install-basic:
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(BINDIR)
|
||||||
|
$(INSTALL) -m 774 $(INSTALL_OPTS) @nagios_name@ $(DESTDIR)$(BINDIR)
|
||||||
|
$(INSTALL) -m 774 $(INSTALL_OPTS) @nagiostats_name@ $(DESTDIR)$(BINDIR)
|
||||||
|
|
||||||
|
strip-post-install:
|
||||||
|
$(STRIP) $(DESTDIR)$(BINDIR)/@nagios_name@
|
||||||
|
$(STRIP) $(DESTDIR)$(BINDIR)/@nagiostats_name@
|
1017
base/broker.c
Normal file
4405
base/checks.c
Normal file
5223
base/commands.c
Normal file
2818
base/config.c
Normal file
1847
base/events.c
Normal file
795
base/flapping.c
Normal file
@ -0,0 +1,795 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* FLAPPING.C - State flap detection and handling routines for Nagios
|
||||||
|
*
|
||||||
|
* Copyright (c) 2001-2009 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 05-15-2009
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*********** COMMON HEADER FILES ***********/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
#include "../include/comments.h"
|
||||||
|
#include "../include/statusdata.h"
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
#include "../include/broker.h"
|
||||||
|
|
||||||
|
extern int interval_length;
|
||||||
|
|
||||||
|
extern int enable_flap_detection;
|
||||||
|
|
||||||
|
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 host *host_list;
|
||||||
|
extern service *service_list;
|
||||||
|
|
||||||
|
extern unsigned long modified_host_process_attributes;
|
||||||
|
extern unsigned long modified_service_process_attributes;
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/******************** FLAP DETECTION FUNCTIONS ********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* detects service flapping */
|
||||||
|
void check_for_service_flapping(service *svc, int update, int allow_flapstart_notification) {
|
||||||
|
int update_history = TRUE;
|
||||||
|
int is_flapping = FALSE;
|
||||||
|
register int x = 0;
|
||||||
|
register int y = 0;
|
||||||
|
int last_state_history_value = STATE_OK;
|
||||||
|
double curved_changes = 0.0;
|
||||||
|
double curved_percent_change = 0.0;
|
||||||
|
double low_threshold = 0.0;
|
||||||
|
double high_threshold = 0.0;
|
||||||
|
double low_curve_value = 0.75;
|
||||||
|
double high_curve_value = 1.25;
|
||||||
|
|
||||||
|
/* large install tweaks skips all flap detection logic - including state change calculation */
|
||||||
|
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_service_flapping()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Checking service '%s' on host '%s' for flapping...\n", svc->description, svc->host_name);
|
||||||
|
|
||||||
|
/* if this is a soft service state and not a soft recovery, don't record this in the history */
|
||||||
|
/* only hard states and soft recoveries get recorded for flap detection */
|
||||||
|
if(svc->state_type == SOFT_STATE && svc->current_state != STATE_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* what threshold values should we use (global or service-specific)? */
|
||||||
|
low_threshold = (svc->low_flap_threshold <= 0.0) ? low_service_flap_threshold : svc->low_flap_threshold;
|
||||||
|
high_threshold = (svc->high_flap_threshold <= 0.0) ? high_service_flap_threshold : svc->high_flap_threshold;
|
||||||
|
|
||||||
|
update_history = update;
|
||||||
|
|
||||||
|
/* should we update state history for this state? */
|
||||||
|
if(update_history == TRUE) {
|
||||||
|
|
||||||
|
if(svc->current_state == STATE_OK && svc->flap_detection_on_ok == FALSE)
|
||||||
|
update_history = FALSE;
|
||||||
|
if(svc->current_state == STATE_WARNING && svc->flap_detection_on_warning == FALSE)
|
||||||
|
update_history = FALSE;
|
||||||
|
if(svc->current_state == STATE_UNKNOWN && svc->flap_detection_on_unknown == FALSE)
|
||||||
|
update_history = FALSE;
|
||||||
|
if(svc->current_state == STATE_CRITICAL && svc->flap_detection_on_critical == FALSE)
|
||||||
|
update_history = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* record current service state */
|
||||||
|
if(update_history == TRUE) {
|
||||||
|
|
||||||
|
/* record the current state in the state history */
|
||||||
|
svc->state_history[svc->state_history_index] = svc->current_state;
|
||||||
|
|
||||||
|
/* increment state history index to next available slot */
|
||||||
|
svc->state_history_index++;
|
||||||
|
if(svc->state_history_index >= MAX_STATE_HISTORY_ENTRIES)
|
||||||
|
svc->state_history_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate overall and curved percent state changes */
|
||||||
|
for(x = 0, y = svc->state_history_index; x < MAX_STATE_HISTORY_ENTRIES; x++) {
|
||||||
|
|
||||||
|
if(x == 0) {
|
||||||
|
last_state_history_value = svc->state_history[y];
|
||||||
|
y++;
|
||||||
|
if(y >= MAX_STATE_HISTORY_ENTRIES)
|
||||||
|
y = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(last_state_history_value != svc->state_history[y])
|
||||||
|
curved_changes += (((double)(x - 1) * (high_curve_value - low_curve_value)) / ((double)(MAX_STATE_HISTORY_ENTRIES - 2))) + low_curve_value;
|
||||||
|
|
||||||
|
last_state_history_value = svc->state_history[y];
|
||||||
|
|
||||||
|
y++;
|
||||||
|
if(y >= MAX_STATE_HISTORY_ENTRIES)
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate overall percent change in state */
|
||||||
|
curved_percent_change = (double)(((double)curved_changes * 100.0) / (double)(MAX_STATE_HISTORY_ENTRIES - 1));
|
||||||
|
|
||||||
|
svc->percent_state_change = curved_percent_change;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 2, "LFT=%.2f, HFT=%.2f, CPC=%.2f, PSC=%.2f%%\n", low_threshold, high_threshold, curved_percent_change, curved_percent_change);
|
||||||
|
|
||||||
|
|
||||||
|
/* don't do anything if we don't have flap detection enabled on a program-wide basis */
|
||||||
|
if(enable_flap_detection == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* don't do anything if we don't have flap detection enabled for this service */
|
||||||
|
if(svc->flap_detection_enabled == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* are we flapping, undecided, or what?... */
|
||||||
|
|
||||||
|
/* we're undecided, so don't change the current flap state */
|
||||||
|
if(curved_percent_change > low_threshold && curved_percent_change < high_threshold)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* we're below the lower bound, so we're not flapping */
|
||||||
|
else if(curved_percent_change <= low_threshold)
|
||||||
|
is_flapping = FALSE;
|
||||||
|
|
||||||
|
/* else we're above the upper bound, so we are flapping */
|
||||||
|
else if(curved_percent_change >= high_threshold)
|
||||||
|
is_flapping = TRUE;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Service %s flapping (%.2f%% state change).\n", (is_flapping == TRUE) ? "is" : "is not", curved_percent_change);
|
||||||
|
|
||||||
|
/* did the service just start flapping? */
|
||||||
|
if(is_flapping == TRUE && svc->is_flapping == FALSE)
|
||||||
|
set_service_flap(svc, curved_percent_change, high_threshold, low_threshold, allow_flapstart_notification);
|
||||||
|
|
||||||
|
/* did the service just stop flapping? */
|
||||||
|
else if(is_flapping == FALSE && svc->is_flapping == TRUE)
|
||||||
|
clear_service_flap(svc, curved_percent_change, high_threshold, low_threshold);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* detects host flapping */
|
||||||
|
void check_for_host_flapping(host *hst, int update, int actual_check, int allow_flapstart_notification) {
|
||||||
|
int update_history = TRUE;
|
||||||
|
int is_flapping = FALSE;
|
||||||
|
register int x = 0;
|
||||||
|
register int y = 0;
|
||||||
|
int last_state_history_value = HOST_UP;
|
||||||
|
unsigned long wait_threshold = 0L;
|
||||||
|
double curved_changes = 0.0;
|
||||||
|
double curved_percent_change = 0.0;
|
||||||
|
time_t current_time = 0L;
|
||||||
|
double low_threshold = 0.0;
|
||||||
|
double high_threshold = 0.0;
|
||||||
|
double low_curve_value = 0.75;
|
||||||
|
double high_curve_value = 1.25;
|
||||||
|
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "check_for_host_flapping()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Checking host '%s' for flapping...\n", hst->name);
|
||||||
|
|
||||||
|
time(¤t_time);
|
||||||
|
|
||||||
|
/* period to wait for updating archived state info if we have no state change */
|
||||||
|
if(hst->total_services == 0)
|
||||||
|
wait_threshold = hst->notification_interval * interval_length;
|
||||||
|
else
|
||||||
|
wait_threshold = (hst->total_service_check_interval * interval_length) / hst->total_services;
|
||||||
|
|
||||||
|
update_history = update;
|
||||||
|
|
||||||
|
/* should we update state history for this state? */
|
||||||
|
if(update_history == TRUE) {
|
||||||
|
|
||||||
|
if(hst->current_state == HOST_UP && hst->flap_detection_on_up == FALSE)
|
||||||
|
update_history = FALSE;
|
||||||
|
if(hst->current_state == HOST_DOWN && hst->flap_detection_on_down == FALSE)
|
||||||
|
update_history = FALSE;
|
||||||
|
if(hst->current_state == HOST_UNREACHABLE && hst->flap_detection_on_unreachable == FALSE)
|
||||||
|
update_history = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we didn't have an actual check, only update if we've waited long enough */
|
||||||
|
if(update_history == TRUE && actual_check == FALSE && (current_time - hst->last_state_history_update) < wait_threshold) {
|
||||||
|
|
||||||
|
update_history = FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* what thresholds should we use (global or host-specific)? */
|
||||||
|
low_threshold = (hst->low_flap_threshold <= 0.0) ? low_host_flap_threshold : hst->low_flap_threshold;
|
||||||
|
high_threshold = (hst->high_flap_threshold <= 0.0) ? high_host_flap_threshold : hst->high_flap_threshold;
|
||||||
|
|
||||||
|
/* record current host state */
|
||||||
|
if(update_history == TRUE) {
|
||||||
|
|
||||||
|
/* update the last record time */
|
||||||
|
hst->last_state_history_update = current_time;
|
||||||
|
|
||||||
|
/* record the current state in the state history */
|
||||||
|
hst->state_history[hst->state_history_index] = hst->current_state;
|
||||||
|
|
||||||
|
/* increment state history index to next available slot */
|
||||||
|
hst->state_history_index++;
|
||||||
|
if(hst->state_history_index >= MAX_STATE_HISTORY_ENTRIES)
|
||||||
|
hst->state_history_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate overall changes in state */
|
||||||
|
for(x = 0, y = hst->state_history_index; x < MAX_STATE_HISTORY_ENTRIES; x++) {
|
||||||
|
|
||||||
|
if(x == 0) {
|
||||||
|
last_state_history_value = hst->state_history[y];
|
||||||
|
y++;
|
||||||
|
if(y >= MAX_STATE_HISTORY_ENTRIES)
|
||||||
|
y = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(last_state_history_value != hst->state_history[y])
|
||||||
|
curved_changes += (((double)(x - 1) * (high_curve_value - low_curve_value)) / ((double)(MAX_STATE_HISTORY_ENTRIES - 2))) + low_curve_value;
|
||||||
|
|
||||||
|
last_state_history_value = hst->state_history[y];
|
||||||
|
|
||||||
|
y++;
|
||||||
|
if(y >= MAX_STATE_HISTORY_ENTRIES)
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate overall percent change in state */
|
||||||
|
curved_percent_change = (double)(((double)curved_changes * 100.0) / (double)(MAX_STATE_HISTORY_ENTRIES - 1));
|
||||||
|
|
||||||
|
hst->percent_state_change = curved_percent_change;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 2, "LFT=%.2f, HFT=%.2f, CPC=%.2f, PSC=%.2f%%\n", low_threshold, high_threshold, curved_percent_change, curved_percent_change);
|
||||||
|
|
||||||
|
|
||||||
|
/* don't do anything if we don't have flap detection enabled on a program-wide basis */
|
||||||
|
if(enable_flap_detection == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* don't do anything if we don't have flap detection enabled for this host */
|
||||||
|
if(hst->flap_detection_enabled == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* are we flapping, undecided, or what?... */
|
||||||
|
|
||||||
|
/* we're undecided, so don't change the current flap state */
|
||||||
|
if(curved_percent_change > low_threshold && curved_percent_change < high_threshold)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* we're below the lower bound, so we're not flapping */
|
||||||
|
else if(curved_percent_change <= low_threshold)
|
||||||
|
is_flapping = FALSE;
|
||||||
|
|
||||||
|
/* else we're above the upper bound, so we are flapping */
|
||||||
|
else if(curved_percent_change >= high_threshold)
|
||||||
|
is_flapping = TRUE;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Host %s flapping (%.2f%% state change).\n", (is_flapping == TRUE) ? "is" : "is not", curved_percent_change);
|
||||||
|
|
||||||
|
/* did the host just start flapping? */
|
||||||
|
if(is_flapping == TRUE && hst->is_flapping == FALSE)
|
||||||
|
set_host_flap(hst, curved_percent_change, high_threshold, low_threshold, allow_flapstart_notification);
|
||||||
|
|
||||||
|
/* did the host just stop flapping? */
|
||||||
|
else if(is_flapping == FALSE && hst->is_flapping == TRUE)
|
||||||
|
clear_host_flap(hst, curved_percent_change, high_threshold, low_threshold);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/********************* FLAP HANDLING FUNCTIONS ********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* handles a service that is flapping */
|
||||||
|
void set_service_flap(service *svc, double percent_change, double high_threshold, double low_threshold, int allow_flapstart_notification) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "set_service_flap()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Service '%s' on host '%s' started flapping!\n", svc->description, svc->host_name);
|
||||||
|
|
||||||
|
/* log a notice - this one is parsed by the history CGI */
|
||||||
|
logit(NSLOG_RUNTIME_WARNING, FALSE, "SERVICE FLAPPING ALERT: %s;%s;STARTED; Service appears to have started flapping (%2.1f%% change >= %2.1f%% threshold)\n", svc->host_name, svc->description, percent_change, high_threshold);
|
||||||
|
|
||||||
|
/* add a non-persistent comment to the service */
|
||||||
|
asprintf(&temp_buffer, "Notifications for this service are being suppressed because it was detected as having been flapping between different states (%2.1f%% change >= %2.1f%% threshold). When the service state stabilizes and the flapping stops, notifications will be re-enabled.", percent_change, high_threshold);
|
||||||
|
add_new_service_comment(FLAPPING_COMMENT, svc->host_name, svc->description, time(NULL), "(Nagios Process)", temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(svc->flapping_comment_id));
|
||||||
|
my_free(temp_buffer);
|
||||||
|
|
||||||
|
/* set the flapping indicator */
|
||||||
|
svc->is_flapping = TRUE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_flapping_data(NEBTYPE_FLAPPING_START, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_FLAPPING, svc, percent_change, high_threshold, low_threshold, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* see if we should check to send a recovery notification out when flapping stops */
|
||||||
|
if(svc->current_state != STATE_OK && svc->current_notification_number > 0)
|
||||||
|
svc->check_flapping_recovery_notification = TRUE;
|
||||||
|
else
|
||||||
|
svc->check_flapping_recovery_notification = FALSE;
|
||||||
|
|
||||||
|
/* send a notification */
|
||||||
|
if(allow_flapstart_notification == TRUE)
|
||||||
|
service_notification(svc, NOTIFICATION_FLAPPINGSTART, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* handles a service that has stopped flapping */
|
||||||
|
void clear_service_flap(service *svc, double percent_change, double high_threshold, double low_threshold) {
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "clear_service_flap()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Service '%s' on host '%s' stopped flapping.\n", svc->description, svc->host_name);
|
||||||
|
|
||||||
|
/* log a notice - this one is parsed by the history CGI */
|
||||||
|
logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE FLAPPING ALERT: %s;%s;STOPPED; Service appears to have stopped flapping (%2.1f%% change < %2.1f%% threshold)\n", svc->host_name, svc->description, percent_change, low_threshold);
|
||||||
|
|
||||||
|
/* delete the comment we added earlier */
|
||||||
|
if(svc->flapping_comment_id != 0)
|
||||||
|
delete_service_comment(svc->flapping_comment_id);
|
||||||
|
svc->flapping_comment_id = 0;
|
||||||
|
|
||||||
|
/* clear the flapping indicator */
|
||||||
|
svc->is_flapping = FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_NORMAL, SERVICE_FLAPPING, svc, percent_change, high_threshold, low_threshold, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* send a notification */
|
||||||
|
service_notification(svc, NOTIFICATION_FLAPPINGSTOP, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* should we send a recovery notification? */
|
||||||
|
if(svc->check_flapping_recovery_notification == TRUE && svc->current_state == STATE_OK)
|
||||||
|
service_notification(svc, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* clear the recovery notification flag */
|
||||||
|
svc->check_flapping_recovery_notification = FALSE;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* handles a host that is flapping */
|
||||||
|
void set_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold, int allow_flapstart_notification) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "set_host_flap()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Host '%s' started flapping!\n", hst->name);
|
||||||
|
|
||||||
|
/* log a notice - this one is parsed by the history CGI */
|
||||||
|
logit(NSLOG_RUNTIME_WARNING, FALSE, "HOST FLAPPING ALERT: %s;STARTED; Host appears to have started flapping (%2.1f%% change > %2.1f%% threshold)\n", hst->name, percent_change, high_threshold);
|
||||||
|
|
||||||
|
/* add a non-persistent comment to the host */
|
||||||
|
asprintf(&temp_buffer, "Notifications for this host are being suppressed because it was detected as having been flapping between different states (%2.1f%% change > %2.1f%% threshold). When the host state stabilizes and the flapping stops, notifications will be re-enabled.", percent_change, high_threshold);
|
||||||
|
add_new_host_comment(FLAPPING_COMMENT, hst->name, time(NULL), "(Nagios Process)", temp_buffer, 0, COMMENTSOURCE_INTERNAL, FALSE, (time_t)0, &(hst->flapping_comment_id));
|
||||||
|
my_free(temp_buffer);
|
||||||
|
|
||||||
|
/* set the flapping indicator */
|
||||||
|
hst->is_flapping = TRUE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_flapping_data(NEBTYPE_FLAPPING_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_FLAPPING, hst, percent_change, high_threshold, low_threshold, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* see if we should check to send a recovery notification out when flapping stops */
|
||||||
|
if(hst->current_state != HOST_UP && hst->current_notification_number > 0)
|
||||||
|
hst->check_flapping_recovery_notification = TRUE;
|
||||||
|
else
|
||||||
|
hst->check_flapping_recovery_notification = FALSE;
|
||||||
|
|
||||||
|
/* send a notification */
|
||||||
|
if(allow_flapstart_notification == TRUE)
|
||||||
|
host_notification(hst, NOTIFICATION_FLAPPINGSTART, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* handles a host that has stopped flapping */
|
||||||
|
void clear_host_flap(host *hst, double percent_change, double high_threshold, double low_threshold) {
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "clear_host_flap()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Host '%s' stopped flapping.\n", hst->name);
|
||||||
|
|
||||||
|
/* log a notice - this one is parsed by the history CGI */
|
||||||
|
logit(NSLOG_INFO_MESSAGE, FALSE, "HOST FLAPPING ALERT: %s;STOPPED; Host appears to have stopped flapping (%2.1f%% change < %2.1f%% threshold)\n", hst->name, percent_change, low_threshold);
|
||||||
|
|
||||||
|
/* delete the comment we added earlier */
|
||||||
|
if(hst->flapping_comment_id != 0)
|
||||||
|
delete_host_comment(hst->flapping_comment_id);
|
||||||
|
hst->flapping_comment_id = 0;
|
||||||
|
|
||||||
|
/* clear the flapping indicator */
|
||||||
|
hst->is_flapping = FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_NORMAL, HOST_FLAPPING, hst, percent_change, high_threshold, low_threshold, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* send a notification */
|
||||||
|
host_notification(hst, NOTIFICATION_FLAPPINGSTOP, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* should we send a recovery notification? */
|
||||||
|
if(hst->check_flapping_recovery_notification == TRUE && hst->current_state == HOST_UP)
|
||||||
|
host_notification(hst, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* clear the recovery notification flag */
|
||||||
|
hst->check_flapping_recovery_notification = FALSE;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/***************** FLAP DETECTION STATUS FUNCTIONS ****************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* enables flap detection on a program wide basis */
|
||||||
|
void enable_flap_detection_routines(void) {
|
||||||
|
host *temp_host = NULL;
|
||||||
|
service *temp_service = NULL;
|
||||||
|
unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "enable_flap_detection_routines()\n");
|
||||||
|
|
||||||
|
/* bail out if we're already set */
|
||||||
|
if(enable_flap_detection == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the attribute modified flag */
|
||||||
|
modified_host_process_attributes |= attr;
|
||||||
|
modified_service_process_attributes |= attr;
|
||||||
|
|
||||||
|
/* set flap detection flag */
|
||||||
|
enable_flap_detection = TRUE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, attr, modified_host_process_attributes, attr, modified_service_process_attributes, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* update program status */
|
||||||
|
update_program_status(FALSE);
|
||||||
|
|
||||||
|
/* check for flapping */
|
||||||
|
for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next)
|
||||||
|
check_for_host_flapping(temp_host, FALSE, FALSE, TRUE);
|
||||||
|
for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next)
|
||||||
|
check_for_service_flapping(temp_service, FALSE, TRUE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* disables flap detection on a program wide basis */
|
||||||
|
void disable_flap_detection_routines(void) {
|
||||||
|
host *temp_host = NULL;
|
||||||
|
service *temp_service = NULL;
|
||||||
|
unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "disable_flap_detection_routines()\n");
|
||||||
|
|
||||||
|
/* bail out if we're already set */
|
||||||
|
if(enable_flap_detection == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the attribute modified flag */
|
||||||
|
modified_host_process_attributes |= attr;
|
||||||
|
modified_service_process_attributes |= attr;
|
||||||
|
|
||||||
|
/* set flap detection flag */
|
||||||
|
enable_flap_detection = FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_adaptive_program_data(NEBTYPE_ADAPTIVEPROGRAM_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, CMD_NONE, attr, modified_host_process_attributes, attr, modified_service_process_attributes, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* update program status */
|
||||||
|
update_program_status(FALSE);
|
||||||
|
|
||||||
|
/* handle the details... */
|
||||||
|
for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next)
|
||||||
|
handle_host_flap_detection_disabled(temp_host);
|
||||||
|
for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next)
|
||||||
|
handle_service_flap_detection_disabled(temp_service);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* enables flap detection for a specific host */
|
||||||
|
void enable_host_flap_detection(host *hst) {
|
||||||
|
unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "enable_host_flap_detection()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Enabling flap detection for host '%s'.\n", hst->name);
|
||||||
|
|
||||||
|
/* nothing to do... */
|
||||||
|
if(hst->flap_detection_enabled == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the attribute modified flag */
|
||||||
|
hst->modified_attributes |= attr;
|
||||||
|
|
||||||
|
/* set the flap detection enabled flag */
|
||||||
|
hst->flap_detection_enabled = TRUE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, hst, CMD_NONE, attr, hst->modified_attributes, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check for flapping */
|
||||||
|
check_for_host_flapping(hst, FALSE, FALSE, TRUE);
|
||||||
|
|
||||||
|
/* update host status */
|
||||||
|
update_host_status(hst, FALSE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* disables flap detection for a specific host */
|
||||||
|
void disable_host_flap_detection(host *hst) {
|
||||||
|
unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "disable_host_flap_detection()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Disabling flap detection for host '%s'.\n", hst->name);
|
||||||
|
|
||||||
|
/* nothing to do... */
|
||||||
|
if(hst->flap_detection_enabled == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the attribute modified flag */
|
||||||
|
hst->modified_attributes |= attr;
|
||||||
|
|
||||||
|
/* set the flap detection enabled flag */
|
||||||
|
hst->flap_detection_enabled = FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_adaptive_host_data(NEBTYPE_ADAPTIVEHOST_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, hst, CMD_NONE, attr, hst->modified_attributes, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* handle the details... */
|
||||||
|
handle_host_flap_detection_disabled(hst);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* handles the details for a host when flap detection is disabled (globally or per-host) */
|
||||||
|
void handle_host_flap_detection_disabled(host *hst) {
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_host_flap_detection_disabled()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* if the host was flapping, remove the flapping indicator */
|
||||||
|
if(hst->is_flapping == TRUE) {
|
||||||
|
|
||||||
|
hst->is_flapping = FALSE;
|
||||||
|
|
||||||
|
/* delete the original comment we added earlier */
|
||||||
|
if(hst->flapping_comment_id != 0)
|
||||||
|
delete_host_comment(hst->flapping_comment_id);
|
||||||
|
hst->flapping_comment_id = 0;
|
||||||
|
|
||||||
|
/* log a notice - this one is parsed by the history CGI */
|
||||||
|
logit(NSLOG_INFO_MESSAGE, FALSE, "HOST FLAPPING ALERT: %s;DISABLED; Flap detection has been disabled\n", hst->name);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_DISABLED, HOST_FLAPPING, hst, hst->percent_state_change, 0.0, 0.0, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* send a notification */
|
||||||
|
host_notification(hst, NOTIFICATION_FLAPPINGDISABLED, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* should we send a recovery notification? */
|
||||||
|
if(hst->check_flapping_recovery_notification == TRUE && hst->current_state == HOST_UP)
|
||||||
|
host_notification(hst, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* clear the recovery notification flag */
|
||||||
|
hst->check_flapping_recovery_notification = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update host status */
|
||||||
|
update_host_status(hst, FALSE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* enables flap detection for a specific service */
|
||||||
|
void enable_service_flap_detection(service *svc) {
|
||||||
|
unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "enable_service_flap_detection()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Enabling flap detection for service '%s' on host '%s'.\n", svc->description, svc->host_name);
|
||||||
|
|
||||||
|
/* nothing to do... */
|
||||||
|
if(svc->flap_detection_enabled == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the attribute modified flag */
|
||||||
|
svc->modified_attributes |= attr;
|
||||||
|
|
||||||
|
/* set the flap detection enabled flag */
|
||||||
|
svc->flap_detection_enabled = TRUE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, svc, CMD_NONE, attr, svc->modified_attributes, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check for flapping */
|
||||||
|
check_for_service_flapping(svc, FALSE, TRUE);
|
||||||
|
|
||||||
|
/* update service status */
|
||||||
|
update_service_status(svc, FALSE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* disables flap detection for a specific service */
|
||||||
|
void disable_service_flap_detection(service *svc) {
|
||||||
|
unsigned long attr = MODATTR_FLAP_DETECTION_ENABLED;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "disable_service_flap_detection()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FLAPPING, 1, "Disabling flap detection for service '%s' on host '%s'.\n", svc->description, svc->host_name);
|
||||||
|
|
||||||
|
/* nothing to do... */
|
||||||
|
if(svc->flap_detection_enabled == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the attribute modified flag */
|
||||||
|
svc->modified_attributes |= attr;
|
||||||
|
|
||||||
|
/* set the flap detection enabled flag */
|
||||||
|
svc->flap_detection_enabled = FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_adaptive_service_data(NEBTYPE_ADAPTIVESERVICE_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, svc, CMD_NONE, attr, svc->modified_attributes, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* handle the details... */
|
||||||
|
handle_service_flap_detection_disabled(svc);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* handles the details for a service when flap detection is disabled (globally or per-service) */
|
||||||
|
void handle_service_flap_detection_disabled(service *svc) {
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_service_flap_detection_disabled()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* if the service was flapping, remove the flapping indicator */
|
||||||
|
if(svc->is_flapping == TRUE) {
|
||||||
|
|
||||||
|
svc->is_flapping = FALSE;
|
||||||
|
|
||||||
|
/* delete the original comment we added earlier */
|
||||||
|
if(svc->flapping_comment_id != 0)
|
||||||
|
delete_service_comment(svc->flapping_comment_id);
|
||||||
|
svc->flapping_comment_id = 0;
|
||||||
|
|
||||||
|
/* log a notice - this one is parsed by the history CGI */
|
||||||
|
logit(NSLOG_INFO_MESSAGE, FALSE, "SERVICE FLAPPING ALERT: %s;%s;DISABLED; Flap detection has been disabled\n", svc->host_name, svc->description);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_flapping_data(NEBTYPE_FLAPPING_STOP, NEBFLAG_NONE, NEBATTR_FLAPPING_STOP_DISABLED, SERVICE_FLAPPING, svc, svc->percent_state_change, 0.0, 0.0, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* send a notification */
|
||||||
|
service_notification(svc, NOTIFICATION_FLAPPINGDISABLED, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* should we send a recovery notification? */
|
||||||
|
if(svc->check_flapping_recovery_notification == TRUE && svc->current_state == STATE_OK)
|
||||||
|
service_notification(svc, NOTIFICATION_NORMAL, NULL, NULL, NOTIFICATION_OPTION_NONE);
|
||||||
|
|
||||||
|
/* clear the recovery notification flag */
|
||||||
|
svc->check_flapping_recovery_notification = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update service status */
|
||||||
|
update_service_status(svc, FALSE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
595
base/logging.c
Normal file
@ -0,0 +1,595 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* LOGGING.C - Log file functions for use with Nagios
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/statusdata.h"
|
||||||
|
#include "../include/macros.h"
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
#include "../include/broker.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern char *log_file;
|
||||||
|
extern char *temp_file;
|
||||||
|
extern char *log_archive_path;
|
||||||
|
|
||||||
|
extern host *host_list;
|
||||||
|
extern service *service_list;
|
||||||
|
|
||||||
|
extern int use_syslog;
|
||||||
|
extern int log_service_retries;
|
||||||
|
extern int log_initial_states;
|
||||||
|
|
||||||
|
extern unsigned long logging_options;
|
||||||
|
extern unsigned long syslog_options;
|
||||||
|
|
||||||
|
extern int verify_config;
|
||||||
|
extern int test_scheduling;
|
||||||
|
|
||||||
|
extern time_t last_log_rotation;
|
||||||
|
extern int log_rotation_method;
|
||||||
|
|
||||||
|
extern int daemon_mode;
|
||||||
|
|
||||||
|
extern char *debug_file;
|
||||||
|
extern int debug_level;
|
||||||
|
extern int debug_verbosity;
|
||||||
|
extern unsigned long max_debug_file_size;
|
||||||
|
FILE *debug_file_fp = NULL;
|
||||||
|
|
||||||
|
static pthread_mutex_t debug_fp_lock;
|
||||||
|
|
||||||
|
/* These simple helpers should most likely be elsewhere */
|
||||||
|
static const char *service_state_name(int state) {
|
||||||
|
switch(state) {
|
||||||
|
case STATE_OK:
|
||||||
|
return "OK";
|
||||||
|
case STATE_WARNING:
|
||||||
|
return "WARNING";
|
||||||
|
case STATE_CRITICAL:
|
||||||
|
return "CRITICAL";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *host_state_name(int state) {
|
||||||
|
switch(state) {
|
||||||
|
case HOST_UP:
|
||||||
|
return "UP";
|
||||||
|
case HOST_DOWN:
|
||||||
|
return "DOWN";
|
||||||
|
case HOST_UNREACHABLE:
|
||||||
|
return "UNREACHABLE";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "(unknown)";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *state_type_name(int state_type) {
|
||||||
|
return state_type == HARD_STATE ? "HARD" : "SOFT";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* since we don't want child processes to hang indefinitely
|
||||||
|
* in case they inherit a locked lock, we use soft-locking
|
||||||
|
* here, which basically tries to acquire the lock for a
|
||||||
|
* short while and then gives up, returning -1 to signal
|
||||||
|
* the error
|
||||||
|
*/
|
||||||
|
static inline int soft_lock(pthread_mutex_t *lock) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < 5; i++) {
|
||||||
|
if(!pthread_mutex_trylock(lock)) {
|
||||||
|
/* success */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errno == EDEADLK) {
|
||||||
|
/* we already have the lock */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sleep briefly */
|
||||||
|
usleep(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1; /* we failed to get the lock. Nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/************************ LOGGING FUNCTIONS ***********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* write something to the console */
|
||||||
|
static void write_to_console(char *buffer) {
|
||||||
|
/* should we print to the console? */
|
||||||
|
if(daemon_mode == FALSE)
|
||||||
|
printf("%s\n", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write something to the log file, syslog, and possibly the console */
|
||||||
|
static void write_to_logs_and_console(char *buffer, unsigned long data_type, int display) {
|
||||||
|
register int len = 0;
|
||||||
|
register int x = 0;
|
||||||
|
|
||||||
|
/* strip unnecessary newlines */
|
||||||
|
len = strlen(buffer);
|
||||||
|
for(x = len - 1; x >= 0; x--) {
|
||||||
|
if(buffer[x] == '\n')
|
||||||
|
buffer[x] = '\x0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write messages to the logs */
|
||||||
|
write_to_all_logs(buffer, data_type);
|
||||||
|
|
||||||
|
/* write message to the console */
|
||||||
|
if(display == TRUE) {
|
||||||
|
|
||||||
|
/* don't display warnings if we're just testing scheduling */
|
||||||
|
if(test_scheduling == TRUE && data_type == NSLOG_VERIFICATION_WARNING)
|
||||||
|
return;
|
||||||
|
|
||||||
|
write_to_console(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The main logging function */
|
||||||
|
void logit(int data_type, int display, const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
char *buffer = NULL;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
if(vasprintf(&buffer, fmt, ap) > 0) {
|
||||||
|
write_to_logs_and_console(buffer, data_type, display);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write something to the log file and syslog facility */
|
||||||
|
int write_to_all_logs(char *buffer, unsigned long data_type) {
|
||||||
|
|
||||||
|
/* write to syslog */
|
||||||
|
write_to_syslog(buffer, data_type);
|
||||||
|
|
||||||
|
/* write to main log */
|
||||||
|
write_to_log(buffer, data_type, NULL);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write something to the log file and syslog facility */
|
||||||
|
static void write_to_all_logs_with_timestamp(char *buffer, unsigned long data_type, time_t *timestamp) {
|
||||||
|
/* write to syslog */
|
||||||
|
write_to_syslog(buffer, data_type);
|
||||||
|
|
||||||
|
/* write to main log */
|
||||||
|
write_to_log(buffer, data_type, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write something to the nagios log file */
|
||||||
|
int write_to_log(char *buffer, unsigned long data_type, time_t *timestamp) {
|
||||||
|
FILE *fp = NULL;
|
||||||
|
time_t log_time = 0L;
|
||||||
|
|
||||||
|
if(buffer == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* don't log anything if we're not actually running... */
|
||||||
|
if(verify_config == TRUE || test_scheduling == TRUE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* make sure we can log this type of entry */
|
||||||
|
if(!(data_type & logging_options))
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
fp = fopen(log_file, "a+");
|
||||||
|
if(fp == NULL) {
|
||||||
|
if(daemon_mode == FALSE)
|
||||||
|
printf("Warning: Cannot open log file '%s' for writing\n", log_file);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* what timestamp should we use? */
|
||||||
|
if(timestamp == NULL)
|
||||||
|
time(&log_time);
|
||||||
|
else
|
||||||
|
log_time = *timestamp;
|
||||||
|
|
||||||
|
/* strip any newlines from the end of the buffer */
|
||||||
|
strip(buffer);
|
||||||
|
|
||||||
|
/* write the buffer to the log file */
|
||||||
|
fprintf(fp, "[%lu] %s\n", log_time, buffer);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to the event broker */
|
||||||
|
broker_log_data(NEBTYPE_LOG_DATA, NEBFLAG_NONE, NEBATTR_NONE, buffer, data_type, log_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write something to the syslog facility */
|
||||||
|
int write_to_syslog(char *buffer, unsigned long data_type) {
|
||||||
|
|
||||||
|
if(buffer == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* don't log anything if we're not actually running... */
|
||||||
|
if(verify_config == TRUE || test_scheduling == TRUE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* bail out if we shouldn't write to syslog */
|
||||||
|
if(use_syslog == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* make sure we should log this type of entry */
|
||||||
|
if(!(data_type & syslog_options))
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* write the buffer to the syslog facility */
|
||||||
|
syslog(LOG_USER | LOG_INFO, "%s", buffer);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write a service problem/recovery to the nagios log file */
|
||||||
|
int log_service_event(service *svc) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
unsigned long log_options = 0L;
|
||||||
|
host *temp_host = NULL;
|
||||||
|
|
||||||
|
/* don't log soft errors if the user doesn't want to */
|
||||||
|
if(svc->state_type == SOFT_STATE && !log_service_retries)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* get the log options */
|
||||||
|
if(svc->current_state == STATE_UNKNOWN)
|
||||||
|
log_options = NSLOG_SERVICE_UNKNOWN;
|
||||||
|
else if(svc->current_state == STATE_WARNING)
|
||||||
|
log_options = NSLOG_SERVICE_WARNING;
|
||||||
|
else if(svc->current_state == STATE_CRITICAL)
|
||||||
|
log_options = NSLOG_SERVICE_CRITICAL;
|
||||||
|
else
|
||||||
|
log_options = NSLOG_SERVICE_OK;
|
||||||
|
|
||||||
|
/* find the associated host */
|
||||||
|
if((temp_host = svc->host_ptr) == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
asprintf(&temp_buffer, "SERVICE ALERT: %s;%s;%s;%s;%d;%s\n",
|
||||||
|
svc->host_name, svc->description,
|
||||||
|
service_state_name(svc->current_state),
|
||||||
|
state_type_name(svc->state_type),
|
||||||
|
svc->current_attempt,
|
||||||
|
(svc->plugin_output == NULL) ? "" : svc->plugin_output);
|
||||||
|
|
||||||
|
write_to_all_logs(temp_buffer, log_options);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write a host problem/recovery to the log file */
|
||||||
|
int log_host_event(host *hst) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
unsigned long log_options = 0L;
|
||||||
|
|
||||||
|
/* get the log options */
|
||||||
|
if(hst->current_state == HOST_DOWN)
|
||||||
|
log_options = NSLOG_HOST_DOWN;
|
||||||
|
else if(hst->current_state == HOST_UNREACHABLE)
|
||||||
|
log_options = NSLOG_HOST_UNREACHABLE;
|
||||||
|
else
|
||||||
|
log_options = NSLOG_HOST_UP;
|
||||||
|
|
||||||
|
asprintf(&temp_buffer, "HOST ALERT: %s;%s;%s;%d;%s\n",
|
||||||
|
hst->name,
|
||||||
|
host_state_name(hst->current_state),
|
||||||
|
state_type_name(hst->state_type),
|
||||||
|
hst->current_attempt,
|
||||||
|
(hst->plugin_output == NULL) ? "" : hst->plugin_output);
|
||||||
|
|
||||||
|
write_to_all_logs(temp_buffer, log_options);
|
||||||
|
|
||||||
|
my_free(temp_buffer);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* logs host states */
|
||||||
|
int log_host_states(int type, time_t *timestamp) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
host *temp_host = NULL;;
|
||||||
|
|
||||||
|
/* bail if we shouldn't be logging initial states */
|
||||||
|
if(type == INITIAL_STATES && log_initial_states == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {
|
||||||
|
|
||||||
|
asprintf(&temp_buffer, "%s HOST STATE: %s;%s;%s;%d;%s\n", (type == INITIAL_STATES) ? "INITIAL" : "CURRENT",
|
||||||
|
temp_host->name,
|
||||||
|
host_state_name(temp_host->current_state),
|
||||||
|
state_type_name(temp_host->state_type),
|
||||||
|
temp_host->current_attempt,
|
||||||
|
(temp_host->plugin_output == NULL) ? "" : temp_host->plugin_output);
|
||||||
|
|
||||||
|
write_to_all_logs_with_timestamp(temp_buffer, NSLOG_INFO_MESSAGE, timestamp);
|
||||||
|
|
||||||
|
my_free(temp_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* logs service states */
|
||||||
|
int log_service_states(int type, time_t *timestamp) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
service *temp_service = NULL;
|
||||||
|
host *temp_host = NULL;;
|
||||||
|
|
||||||
|
/* bail if we shouldn't be logging initial states */
|
||||||
|
if(type == INITIAL_STATES && log_initial_states == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
|
||||||
|
|
||||||
|
/* find the associated host */
|
||||||
|
if((temp_host = temp_service->host_ptr) == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
asprintf(&temp_buffer, "%s SERVICE STATE: %s;%s;%s;%s;%d;%s\n",
|
||||||
|
(type == INITIAL_STATES) ? "INITIAL" : "CURRENT",
|
||||||
|
temp_service->host_name, temp_service->description,
|
||||||
|
service_state_name(temp_service->current_state),
|
||||||
|
state_type_name(temp_service->state_type),
|
||||||
|
temp_service->current_attempt,
|
||||||
|
temp_service->plugin_output);
|
||||||
|
|
||||||
|
write_to_all_logs_with_timestamp(temp_buffer, NSLOG_INFO_MESSAGE, timestamp);
|
||||||
|
|
||||||
|
my_free(temp_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* rotates the main log file */
|
||||||
|
int rotate_log_file(time_t rotation_time) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
char method_string[16] = "";
|
||||||
|
char *log_archive = NULL;
|
||||||
|
struct tm *t, tm_s;
|
||||||
|
int rename_result = 0;
|
||||||
|
int stat_result = -1;
|
||||||
|
struct stat log_file_stat;
|
||||||
|
|
||||||
|
if(log_rotation_method == LOG_ROTATION_NONE) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
else if(log_rotation_method == LOG_ROTATION_HOURLY)
|
||||||
|
strcpy(method_string, "HOURLY");
|
||||||
|
else if(log_rotation_method == LOG_ROTATION_DAILY)
|
||||||
|
strcpy(method_string, "DAILY");
|
||||||
|
else if(log_rotation_method == LOG_ROTATION_WEEKLY)
|
||||||
|
strcpy(method_string, "WEEKLY");
|
||||||
|
else if(log_rotation_method == LOG_ROTATION_MONTHLY)
|
||||||
|
strcpy(method_string, "MONTHLY");
|
||||||
|
else
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* update the last log rotation time and status log */
|
||||||
|
last_log_rotation = time(NULL);
|
||||||
|
update_program_status(FALSE);
|
||||||
|
|
||||||
|
t = localtime_r(&rotation_time, &tm_s);
|
||||||
|
|
||||||
|
stat_result = stat(log_file, &log_file_stat);
|
||||||
|
|
||||||
|
/* get the archived filename to use */
|
||||||
|
asprintf(&log_archive, "%s%snagios-%02d-%02d-%d-%02d.log", log_archive_path, (log_archive_path[strlen(log_archive_path) - 1] == '/') ? "" : "/", t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour);
|
||||||
|
|
||||||
|
/* rotate the log file */
|
||||||
|
rename_result = my_rename(log_file, log_archive);
|
||||||
|
|
||||||
|
if(rename_result) {
|
||||||
|
my_free(log_archive);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* record the log rotation after it has been done... */
|
||||||
|
asprintf(&temp_buffer, "LOG ROTATION: %s\n", method_string);
|
||||||
|
write_to_all_logs_with_timestamp(temp_buffer, NSLOG_PROCESS_INFO, &rotation_time);
|
||||||
|
my_free(temp_buffer);
|
||||||
|
|
||||||
|
/* record log file version format */
|
||||||
|
write_log_file_info(&rotation_time);
|
||||||
|
|
||||||
|
if(stat_result == 0) {
|
||||||
|
chmod(log_file, log_file_stat.st_mode);
|
||||||
|
chown(log_file, log_file_stat.st_uid, log_file_stat.st_gid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* log current host and service state */
|
||||||
|
log_host_states(CURRENT_STATES, &rotation_time);
|
||||||
|
log_service_states(CURRENT_STATES, &rotation_time);
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(log_archive);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* record log file version/info */
|
||||||
|
int write_log_file_info(time_t *timestamp) {
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
|
||||||
|
/* write log version */
|
||||||
|
asprintf(&temp_buffer, "LOG VERSION: %s\n", LOG_VERSION_2);
|
||||||
|
write_to_all_logs_with_timestamp(temp_buffer, NSLOG_PROCESS_INFO, timestamp);
|
||||||
|
my_free(temp_buffer);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* opens the debug log for writing */
|
||||||
|
int open_debug_log(void) {
|
||||||
|
|
||||||
|
/* don't do anything if we're not actually running... */
|
||||||
|
if(verify_config == TRUE || test_scheduling == TRUE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* don't do anything if we're not debugging */
|
||||||
|
if(debug_level == DEBUGL_NONE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
if((debug_file_fp = fopen(debug_file, "a+")) == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* change the ownership of the debug log. This is done so that if Nagios
|
||||||
|
receives a HUP signal, it will be owned by a user that can reopen the file */
|
||||||
|
int chown_debug_log(uid_t uid, gid_t gid) {
|
||||||
|
|
||||||
|
/* don't do anything if we're not actually running... */
|
||||||
|
if(verify_config == TRUE || test_scheduling == TRUE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* don't do anything if we're not debugging */
|
||||||
|
if(debug_level == DEBUGL_NONE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
if(chown(debug_file, uid, gid) < 0) {
|
||||||
|
logit(NSLOG_RUNTIME_WARNING, TRUE,
|
||||||
|
"Failed to change ownership on debug log: %s.",
|
||||||
|
strerror(errno));
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* closes the debug log */
|
||||||
|
int close_debug_log(void) {
|
||||||
|
|
||||||
|
if(debug_file_fp != NULL)
|
||||||
|
fclose(debug_file_fp);
|
||||||
|
|
||||||
|
debug_file_fp = NULL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* write to the debug log */
|
||||||
|
int log_debug_info(int level, int verbosity, const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
char *temp_path = NULL;
|
||||||
|
struct timeval current_time;
|
||||||
|
|
||||||
|
if(!(debug_level == DEBUGL_ALL || (level & debug_level)))
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
if(verbosity > debug_verbosity)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
if(debug_file_fp == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lock it so concurrent threads don't stomp on each other's
|
||||||
|
* writings. We maintain the lock until we've (optionally)
|
||||||
|
* renamed the file.
|
||||||
|
* If soft_lock() fails we return early.
|
||||||
|
*/
|
||||||
|
if(soft_lock(&debug_fp_lock) < 0)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* write the timestamp */
|
||||||
|
gettimeofday(¤t_time, NULL);
|
||||||
|
fprintf(debug_file_fp, "[%lu.%06lu] [%03d.%d] [pid=%lu] ", current_time.tv_sec, current_time.tv_usec, level, verbosity, (unsigned long)getpid());
|
||||||
|
|
||||||
|
/* write the data */
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(debug_file_fp, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
/* flush, so we don't have problems tailing or when fork()ing */
|
||||||
|
fflush(debug_file_fp);
|
||||||
|
|
||||||
|
/* if file has grown beyond max, rotate it */
|
||||||
|
if((unsigned long)ftell(debug_file_fp) > max_debug_file_size && max_debug_file_size > 0L) {
|
||||||
|
|
||||||
|
/* close the file */
|
||||||
|
close_debug_log();
|
||||||
|
|
||||||
|
/* rotate the log file */
|
||||||
|
asprintf(&temp_path, "%s.old", debug_file);
|
||||||
|
if(temp_path) {
|
||||||
|
|
||||||
|
/* unlink the old debug file */
|
||||||
|
unlink(temp_path);
|
||||||
|
|
||||||
|
/* rotate the debug file */
|
||||||
|
my_rename(debug_file, temp_path);
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(temp_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open a new file */
|
||||||
|
open_debug_log();
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&debug_fp_lock);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
937
base/nagios.c
Normal file
@ -0,0 +1,937 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* NAGIOS.C - Core Program Code For Nagios
|
||||||
|
*
|
||||||
|
* Program: Nagios Core
|
||||||
|
* Version: 3.5.1
|
||||||
|
* License: GPL
|
||||||
|
* Copyright (c) 2009-2010 Nagios Core Development Team and Community Contributors
|
||||||
|
* Copyright (c) 1999-2009 Ethan Galstad
|
||||||
|
*
|
||||||
|
* First Written: 01-28-1999 (start of development)
|
||||||
|
* Last Modified:
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* Nagios is a network monitoring tool that will check hosts and services
|
||||||
|
* that you specify. It has the ability to notify contacts via email, pager,
|
||||||
|
* or other user-defined methods when a service or host goes down and
|
||||||
|
* recovers. Service and host monitoring is done through the use of external
|
||||||
|
* plugins which can be developed independently of 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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
#include "../include/comments.h"
|
||||||
|
#include "../include/downtime.h"
|
||||||
|
#include "../include/statusdata.h"
|
||||||
|
#include "../include/macros.h"
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
#include "../include/sretention.h"
|
||||||
|
#include "../include/perfdata.h"
|
||||||
|
#include "../include/broker.h"
|
||||||
|
#include "../include/nebmods.h"
|
||||||
|
#include "../include/nebmodules.h"
|
||||||
|
|
||||||
|
/*#define DEBUG_MEMORY 1*/
|
||||||
|
#ifdef DEBUG_MEMORY
|
||||||
|
#include <mcheck.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char *config_file = NULL;
|
||||||
|
char *log_file = NULL;
|
||||||
|
char *command_file = NULL;
|
||||||
|
char *temp_file = NULL;
|
||||||
|
char *temp_path = NULL;
|
||||||
|
char *check_result_path = NULL;
|
||||||
|
char *lock_file = NULL;
|
||||||
|
char *log_archive_path = NULL;
|
||||||
|
char *p1_file = NULL; /**** EMBEDDED PERL ****/
|
||||||
|
char *auth_file = NULL; /**** EMBEDDED PERL INTERPRETER AUTH FILE ****/
|
||||||
|
char *nagios_user = NULL;
|
||||||
|
char *nagios_group = NULL;
|
||||||
|
|
||||||
|
char *global_host_event_handler = NULL;
|
||||||
|
char *global_service_event_handler = NULL;
|
||||||
|
command *global_host_event_handler_ptr = NULL;
|
||||||
|
command *global_service_event_handler_ptr = NULL;
|
||||||
|
|
||||||
|
char *ocsp_command = NULL;
|
||||||
|
char *ochp_command = NULL;
|
||||||
|
command *ocsp_command_ptr = NULL;
|
||||||
|
command *ochp_command_ptr = NULL;
|
||||||
|
|
||||||
|
char *illegal_object_chars = NULL;
|
||||||
|
char *illegal_output_chars = NULL;
|
||||||
|
|
||||||
|
int use_regexp_matches = FALSE;
|
||||||
|
int use_true_regexp_matching = FALSE;
|
||||||
|
|
||||||
|
int use_syslog = DEFAULT_USE_SYSLOG;
|
||||||
|
int log_notifications = DEFAULT_NOTIFICATION_LOGGING;
|
||||||
|
int log_service_retries = DEFAULT_LOG_SERVICE_RETRIES;
|
||||||
|
int log_host_retries = DEFAULT_LOG_HOST_RETRIES;
|
||||||
|
int log_event_handlers = DEFAULT_LOG_EVENT_HANDLERS;
|
||||||
|
int log_initial_states = DEFAULT_LOG_INITIAL_STATES;
|
||||||
|
int log_external_commands = DEFAULT_LOG_EXTERNAL_COMMANDS;
|
||||||
|
int log_passive_checks = DEFAULT_LOG_PASSIVE_CHECKS;
|
||||||
|
|
||||||
|
unsigned long logging_options = 0;
|
||||||
|
unsigned long syslog_options = 0;
|
||||||
|
|
||||||
|
int service_check_timeout = DEFAULT_SERVICE_CHECK_TIMEOUT;
|
||||||
|
int service_check_timeout_state = STATE_CRITICAL;
|
||||||
|
int host_check_timeout = DEFAULT_HOST_CHECK_TIMEOUT;
|
||||||
|
int event_handler_timeout = DEFAULT_EVENT_HANDLER_TIMEOUT;
|
||||||
|
int notification_timeout = DEFAULT_NOTIFICATION_TIMEOUT;
|
||||||
|
int ocsp_timeout = DEFAULT_OCSP_TIMEOUT;
|
||||||
|
int ochp_timeout = DEFAULT_OCHP_TIMEOUT;
|
||||||
|
|
||||||
|
double sleep_time = DEFAULT_SLEEP_TIME;
|
||||||
|
int interval_length = DEFAULT_INTERVAL_LENGTH;
|
||||||
|
int service_inter_check_delay_method = ICD_SMART;
|
||||||
|
int host_inter_check_delay_method = ICD_SMART;
|
||||||
|
int service_interleave_factor_method = ILF_SMART;
|
||||||
|
int max_host_check_spread = DEFAULT_HOST_CHECK_SPREAD;
|
||||||
|
int max_service_check_spread = DEFAULT_SERVICE_CHECK_SPREAD;
|
||||||
|
|
||||||
|
int command_check_interval = DEFAULT_COMMAND_CHECK_INTERVAL;
|
||||||
|
int check_reaper_interval = DEFAULT_CHECK_REAPER_INTERVAL;
|
||||||
|
int max_check_reaper_time = DEFAULT_MAX_REAPER_TIME;
|
||||||
|
int service_freshness_check_interval = DEFAULT_FRESHNESS_CHECK_INTERVAL;
|
||||||
|
int host_freshness_check_interval = DEFAULT_FRESHNESS_CHECK_INTERVAL;
|
||||||
|
int auto_rescheduling_interval = DEFAULT_AUTO_RESCHEDULING_INTERVAL;
|
||||||
|
|
||||||
|
int check_external_commands = DEFAULT_CHECK_EXTERNAL_COMMANDS;
|
||||||
|
int check_orphaned_services = DEFAULT_CHECK_ORPHANED_SERVICES;
|
||||||
|
int check_orphaned_hosts = DEFAULT_CHECK_ORPHANED_HOSTS;
|
||||||
|
int check_service_freshness = DEFAULT_CHECK_SERVICE_FRESHNESS;
|
||||||
|
int check_host_freshness = DEFAULT_CHECK_HOST_FRESHNESS;
|
||||||
|
int auto_reschedule_checks = DEFAULT_AUTO_RESCHEDULE_CHECKS;
|
||||||
|
int auto_rescheduling_window = DEFAULT_AUTO_RESCHEDULING_WINDOW;
|
||||||
|
|
||||||
|
int additional_freshness_latency = DEFAULT_ADDITIONAL_FRESHNESS_LATENCY;
|
||||||
|
|
||||||
|
int check_for_updates = DEFAULT_CHECK_FOR_UPDATES;
|
||||||
|
int bare_update_check = DEFAULT_BARE_UPDATE_CHECK;
|
||||||
|
time_t last_update_check = 0L;
|
||||||
|
unsigned long update_uid = 0L;
|
||||||
|
int update_available = FALSE;
|
||||||
|
char *last_program_version = NULL;
|
||||||
|
char *new_program_version = NULL;
|
||||||
|
|
||||||
|
time_t last_command_check = 0L;
|
||||||
|
time_t last_command_status_update = 0L;
|
||||||
|
time_t last_log_rotation = 0L;
|
||||||
|
time_t last_program_stop = 0L;
|
||||||
|
|
||||||
|
int use_aggressive_host_checking = DEFAULT_AGGRESSIVE_HOST_CHECKING;
|
||||||
|
unsigned long cached_host_check_horizon = DEFAULT_CACHED_HOST_CHECK_HORIZON;
|
||||||
|
unsigned long cached_service_check_horizon = DEFAULT_CACHED_SERVICE_CHECK_HORIZON;
|
||||||
|
int enable_predictive_host_dependency_checks = DEFAULT_ENABLE_PREDICTIVE_HOST_DEPENDENCY_CHECKS;
|
||||||
|
int enable_predictive_service_dependency_checks = DEFAULT_ENABLE_PREDICTIVE_SERVICE_DEPENDENCY_CHECKS;
|
||||||
|
|
||||||
|
int soft_state_dependencies = FALSE;
|
||||||
|
|
||||||
|
int retain_state_information = FALSE;
|
||||||
|
int retention_update_interval = DEFAULT_RETENTION_UPDATE_INTERVAL;
|
||||||
|
int use_retained_program_state = TRUE;
|
||||||
|
int use_retained_scheduling_info = FALSE;
|
||||||
|
int retention_scheduling_horizon = DEFAULT_RETENTION_SCHEDULING_HORIZON;
|
||||||
|
unsigned long modified_host_process_attributes = MODATTR_NONE;
|
||||||
|
unsigned long modified_service_process_attributes = MODATTR_NONE;
|
||||||
|
unsigned long retained_host_attribute_mask = 0L;
|
||||||
|
unsigned long retained_service_attribute_mask = 0L;
|
||||||
|
unsigned long retained_contact_host_attribute_mask = 0L;
|
||||||
|
unsigned long retained_contact_service_attribute_mask = 0L;
|
||||||
|
unsigned long retained_process_host_attribute_mask = 0L;
|
||||||
|
unsigned long retained_process_service_attribute_mask = 0L;
|
||||||
|
|
||||||
|
unsigned long next_comment_id = 0L;
|
||||||
|
unsigned long next_downtime_id = 0L;
|
||||||
|
unsigned long next_event_id = 0L;
|
||||||
|
unsigned long next_problem_id = 0L;
|
||||||
|
unsigned long next_notification_id = 0L;
|
||||||
|
|
||||||
|
int log_rotation_method = LOG_ROTATION_NONE;
|
||||||
|
|
||||||
|
int sigshutdown = FALSE;
|
||||||
|
int sigrestart = FALSE;
|
||||||
|
char *sigs[35] = {"EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "UNUSED", "ZERR", "DEBUG", (char *)NULL};
|
||||||
|
int caught_signal = FALSE;
|
||||||
|
int sig_id = 0;
|
||||||
|
|
||||||
|
int restarting = FALSE;
|
||||||
|
|
||||||
|
int verify_config = FALSE;
|
||||||
|
int verify_object_relationships = TRUE;
|
||||||
|
int verify_circular_paths = TRUE;
|
||||||
|
int test_scheduling = FALSE;
|
||||||
|
int precache_objects = FALSE;
|
||||||
|
int use_precached_objects = FALSE;
|
||||||
|
|
||||||
|
int daemon_mode = FALSE;
|
||||||
|
int daemon_dumps_core = TRUE;
|
||||||
|
|
||||||
|
int max_parallel_service_checks = DEFAULT_MAX_PARALLEL_SERVICE_CHECKS;
|
||||||
|
int currently_running_service_checks = 0;
|
||||||
|
int currently_running_host_checks = 0;
|
||||||
|
|
||||||
|
time_t program_start = 0L;
|
||||||
|
time_t event_start = 0L;
|
||||||
|
int nagios_pid = 0;
|
||||||
|
int enable_notifications = TRUE;
|
||||||
|
int execute_service_checks = TRUE;
|
||||||
|
int accept_passive_service_checks = TRUE;
|
||||||
|
int execute_host_checks = TRUE;
|
||||||
|
int accept_passive_host_checks = TRUE;
|
||||||
|
int enable_event_handlers = TRUE;
|
||||||
|
int obsess_over_services = FALSE;
|
||||||
|
int obsess_over_hosts = FALSE;
|
||||||
|
int enable_failure_prediction = TRUE;
|
||||||
|
|
||||||
|
int translate_passive_host_checks = DEFAULT_TRANSLATE_PASSIVE_HOST_CHECKS;
|
||||||
|
int passive_host_checks_are_soft = DEFAULT_PASSIVE_HOST_CHECKS_SOFT;
|
||||||
|
|
||||||
|
int aggregate_status_updates = TRUE;
|
||||||
|
int status_update_interval = DEFAULT_STATUS_UPDATE_INTERVAL;
|
||||||
|
|
||||||
|
int time_change_threshold = DEFAULT_TIME_CHANGE_THRESHOLD;
|
||||||
|
|
||||||
|
unsigned long event_broker_options = BROKER_NOTHING;
|
||||||
|
|
||||||
|
int process_performance_data = DEFAULT_PROCESS_PERFORMANCE_DATA;
|
||||||
|
|
||||||
|
int enable_flap_detection = DEFAULT_ENABLE_FLAP_DETECTION;
|
||||||
|
|
||||||
|
double low_service_flap_threshold = DEFAULT_LOW_SERVICE_FLAP_THRESHOLD;
|
||||||
|
double high_service_flap_threshold = DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD;
|
||||||
|
double low_host_flap_threshold = DEFAULT_LOW_HOST_FLAP_THRESHOLD;
|
||||||
|
double high_host_flap_threshold = DEFAULT_HIGH_HOST_FLAP_THRESHOLD;
|
||||||
|
|
||||||
|
int use_large_installation_tweaks = DEFAULT_USE_LARGE_INSTALLATION_TWEAKS;
|
||||||
|
int enable_environment_macros = TRUE;
|
||||||
|
int free_child_process_memory = -1;
|
||||||
|
int child_processes_fork_twice = -1;
|
||||||
|
|
||||||
|
int enable_embedded_perl = DEFAULT_ENABLE_EMBEDDED_PERL;
|
||||||
|
int use_embedded_perl_implicitly = DEFAULT_USE_EMBEDDED_PERL_IMPLICITLY;
|
||||||
|
int embedded_perl_initialized = FALSE;
|
||||||
|
|
||||||
|
int date_format = DATE_FORMAT_US;
|
||||||
|
char *use_timezone = NULL;
|
||||||
|
|
||||||
|
int allow_empty_hostgroup_assignment = DEFAULT_ALLOW_EMPTY_HOSTGROUP_ASSIGNMENT;
|
||||||
|
|
||||||
|
int command_file_fd;
|
||||||
|
FILE *command_file_fp;
|
||||||
|
int command_file_created = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
extern contact *contact_list;
|
||||||
|
extern contactgroup *contactgroup_list;
|
||||||
|
extern hostgroup *hostgroup_list;
|
||||||
|
extern command *command_list;
|
||||||
|
extern timeperiod *timeperiod_list;
|
||||||
|
extern serviceescalation *serviceescalation_list;
|
||||||
|
|
||||||
|
notification *notification_list;
|
||||||
|
|
||||||
|
check_result check_result_info;
|
||||||
|
check_result *check_result_list = NULL;
|
||||||
|
unsigned long max_check_result_file_age = DEFAULT_MAX_CHECK_RESULT_AGE;
|
||||||
|
|
||||||
|
dbuf check_result_dbuf;
|
||||||
|
|
||||||
|
circular_buffer external_command_buffer;
|
||||||
|
circular_buffer check_result_buffer;
|
||||||
|
pthread_t worker_threads[TOTAL_WORKER_THREADS];
|
||||||
|
int external_command_buffer_slots = DEFAULT_EXTERNAL_COMMAND_BUFFER_SLOTS;
|
||||||
|
|
||||||
|
check_stats check_statistics[MAX_CHECK_STATS_TYPES];
|
||||||
|
|
||||||
|
char *debug_file;
|
||||||
|
int debug_level = DEFAULT_DEBUG_LEVEL;
|
||||||
|
int debug_verbosity = DEFAULT_DEBUG_VERBOSITY;
|
||||||
|
unsigned long max_debug_file_size = DEFAULT_MAX_DEBUG_FILE_SIZE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Following main() declaration required by older versions of Perl ut 5.00503 */
|
||||||
|
int main(int argc, char **argv, char **env) {
|
||||||
|
int result;
|
||||||
|
int error = FALSE;
|
||||||
|
char *buffer = NULL;
|
||||||
|
int display_license = FALSE;
|
||||||
|
int display_help = FALSE;
|
||||||
|
int c = 0;
|
||||||
|
struct tm *tm, tm_s;
|
||||||
|
time_t now;
|
||||||
|
char datestring[256];
|
||||||
|
nagios_macros *mac;
|
||||||
|
|
||||||
|
mac = get_global_macros();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_GETOPT_H
|
||||||
|
int option_index = 0;
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"version", no_argument, 0, 'V'},
|
||||||
|
{"license", no_argument, 0, 'V'},
|
||||||
|
{"verify-config", no_argument, 0, 'v'},
|
||||||
|
{"daemon", no_argument, 0, 'd'},
|
||||||
|
{"test-scheduling", no_argument, 0, 's'},
|
||||||
|
{"dont-verify-objects", no_argument, 0, 'o'},
|
||||||
|
{"dont-verify-paths", no_argument, 0, 'x'},
|
||||||
|
{"precache-objects", no_argument, 0, 'p'},
|
||||||
|
{"use-precached-objects", no_argument, 0, 'u'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* make sure we have the correct number of command line arguments */
|
||||||
|
if(argc < 2)
|
||||||
|
error = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
/* get all command line arguments */
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
#ifdef HAVE_GETOPT_H
|
||||||
|
c = getopt_long(argc, argv, "+hVvdsoxpu", long_options, &option_index);
|
||||||
|
#else
|
||||||
|
c = getopt(argc, argv, "+hVvdsoxpu");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(c == -1 || c == EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
|
||||||
|
case '?': /* usage */
|
||||||
|
case 'h':
|
||||||
|
display_help = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V': /* version */
|
||||||
|
display_license = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v': /* verify */
|
||||||
|
verify_config = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's': /* scheduling check */
|
||||||
|
test_scheduling = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd': /* daemon mode */
|
||||||
|
daemon_mode = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o': /* don't verify objects */
|
||||||
|
/*
|
||||||
|
verify_object_relationships=FALSE;
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x': /* don't verify circular paths */
|
||||||
|
verify_circular_paths = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p': /* precache object config */
|
||||||
|
precache_objects = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u': /* use precached object config */
|
||||||
|
use_precached_objects = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure we have the right combination of arguments */
|
||||||
|
if(precache_objects == TRUE && (test_scheduling == FALSE && verify_config == FALSE)) {
|
||||||
|
error = TRUE;
|
||||||
|
display_help = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_MEMORY
|
||||||
|
mtrace();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(daemon_mode == FALSE) {
|
||||||
|
printf("\nNagios Core %s\n", PROGRAM_VERSION);
|
||||||
|
printf("Copyright (c) 2009-2011 Nagios Core Development Team and Community Contributors\n");
|
||||||
|
printf("Copyright (c) 1999-2009 Ethan Galstad\n");
|
||||||
|
printf("Last Modified: %s\n", PROGRAM_MODIFICATION_DATE);
|
||||||
|
printf("License: GPL\n\n");
|
||||||
|
printf("Website: http://www.nagios.org\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* just display the license */
|
||||||
|
if(display_license == TRUE) {
|
||||||
|
|
||||||
|
printf("This program is free software; you can redistribute it and/or modify\n");
|
||||||
|
printf("it under the terms of the GNU General Public License version 2 as\n");
|
||||||
|
printf("published by the Free Software Foundation.\n\n");
|
||||||
|
printf("This program is distributed in the hope that it will be useful,\n");
|
||||||
|
printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
|
||||||
|
printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
|
||||||
|
printf("GNU General Public License for more details.\n\n");
|
||||||
|
printf("You should have received a copy of the GNU General Public License\n");
|
||||||
|
printf("along with this program; if not, write to the Free Software\n");
|
||||||
|
printf("Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
|
||||||
|
|
||||||
|
exit(OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure we got the main config file on the command line... */
|
||||||
|
if(optind >= argc)
|
||||||
|
error = TRUE;
|
||||||
|
|
||||||
|
/* if there are no command line options (or if we encountered an error), print usage */
|
||||||
|
if(error == TRUE || display_help == TRUE) {
|
||||||
|
|
||||||
|
printf("Usage: %s [options] <main_config_file>\n", argv[0]);
|
||||||
|
printf("\n");
|
||||||
|
printf("Options:\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" -v, --verify-config Verify all configuration data\n");
|
||||||
|
printf(" -s, --test-scheduling Shows projected/recommended check scheduling and other\n");
|
||||||
|
printf(" diagnostic info based on the current configuration files.\n");
|
||||||
|
/*printf(" -o, --dont-verify-objects Don't verify object relationships - USE WITH CAUTION!\n");*/
|
||||||
|
printf(" -x, --dont-verify-paths Don't check for circular object paths - USE WITH CAUTION!\n");
|
||||||
|
printf(" -p, --precache-objects Precache object configuration - use with -v or -s options\n");
|
||||||
|
printf(" -u, --use-precached-objects Use precached object config file\n");
|
||||||
|
printf(" -d, --daemon Starts Nagios in daemon mode, instead of as a foreground process\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Visit the Nagios website at http://www.nagios.org/ for bug fixes, new\n");
|
||||||
|
printf("releases, online documentation, FAQs, information on subscribing to\n");
|
||||||
|
printf("the mailing lists, and commercial support options for Nagios.\n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
exit(ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the signal handler for the SIGXFSZ signal here because
|
||||||
|
* we may encounter this signal before the other signal handlers
|
||||||
|
* are set.
|
||||||
|
*/
|
||||||
|
signal(SIGXFSZ, handle_sigxfsz);
|
||||||
|
|
||||||
|
/* config file is last argument specified */
|
||||||
|
config_file = (char *)strdup(argv[optind]);
|
||||||
|
if(config_file == NULL) {
|
||||||
|
printf("Error allocating memory.\n");
|
||||||
|
exit(ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure the config file uses an absolute path */
|
||||||
|
if(config_file[0] != '/') {
|
||||||
|
|
||||||
|
/* save the name of the config file */
|
||||||
|
buffer = (char *)strdup(config_file);
|
||||||
|
|
||||||
|
/* reallocate a larger chunk of memory */
|
||||||
|
config_file = (char *)realloc(config_file, MAX_FILENAME_LENGTH);
|
||||||
|
if(config_file == NULL) {
|
||||||
|
printf("Error allocating memory.\n");
|
||||||
|
exit(ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get absolute path of current working directory */
|
||||||
|
getcwd(config_file, MAX_FILENAME_LENGTH);
|
||||||
|
|
||||||
|
/* append a forward slash */
|
||||||
|
strncat(config_file, "/", 1);
|
||||||
|
config_file[MAX_FILENAME_LENGTH - 1] = '\x0';
|
||||||
|
|
||||||
|
/* append the config file to the path */
|
||||||
|
strncat(config_file, buffer, MAX_FILENAME_LENGTH - strlen(config_file) - 1);
|
||||||
|
config_file[MAX_FILENAME_LENGTH - 1] = '\x0';
|
||||||
|
|
||||||
|
my_free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* we're just verifying the configuration... */
|
||||||
|
if(verify_config == TRUE) {
|
||||||
|
|
||||||
|
/* reset program variables */
|
||||||
|
reset_variables();
|
||||||
|
|
||||||
|
printf("Reading configuration data...\n");
|
||||||
|
|
||||||
|
/* read in the configuration files (main config file, resource and object config files) */
|
||||||
|
if((result = read_main_config_file(config_file)) == OK) {
|
||||||
|
|
||||||
|
printf(" Read main config file okay...\n");
|
||||||
|
|
||||||
|
/* drop privileges */
|
||||||
|
if((result = drop_privileges(nagios_user, nagios_group)) == ERROR)
|
||||||
|
printf(" Failed to drop privileges. Aborting.");
|
||||||
|
else {
|
||||||
|
/* read object config files */
|
||||||
|
if((result = read_all_object_data(config_file)) == OK)
|
||||||
|
printf(" Read object config files okay...\n");
|
||||||
|
else
|
||||||
|
printf(" Error processing object config files!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf(" Error processing main config file!\n\n");
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
/* there was a problem reading the config files */
|
||||||
|
if(result != OK) {
|
||||||
|
|
||||||
|
/* if the config filename looks fishy, warn the user */
|
||||||
|
if(!strstr(config_file, "nagios.cfg")) {
|
||||||
|
printf("\n***> The name of the main configuration file looks suspicious...\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" Make sure you are specifying the name of the MAIN configuration file on\n");
|
||||||
|
printf(" the command line and not the name of another configuration file. The\n");
|
||||||
|
printf(" main configuration file is typically '/usr/local/nagios/etc/nagios.cfg'\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n***> One or more problems was encountered while processing the config files...\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" Check your configuration file(s) to ensure that they contain valid\n");
|
||||||
|
printf(" directives and data defintions. If you are upgrading from a previous\n");
|
||||||
|
printf(" version of Nagios, you should be aware that some variables/definitions\n");
|
||||||
|
printf(" may have been removed or modified in this version. Make sure to read\n");
|
||||||
|
printf(" the HTML documentation regarding the config files, as well as the\n");
|
||||||
|
printf(" 'Whats New' section to find out what has changed.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the config files were okay, so run the pre-flight check */
|
||||||
|
else {
|
||||||
|
|
||||||
|
printf("Running pre-flight check on configuration data...\n\n");
|
||||||
|
|
||||||
|
/* run the pre-flight check to make sure things look okay... */
|
||||||
|
result = pre_flight_check();
|
||||||
|
|
||||||
|
if(result == OK)
|
||||||
|
printf("\nThings look okay - No serious problems were detected during the pre-flight check\n");
|
||||||
|
else {
|
||||||
|
printf("\n***> One or more problems was encountered while running the pre-flight check...\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" Check your configuration file(s) to ensure that they contain valid\n");
|
||||||
|
printf(" directives and data defintions. If you are upgrading from a previous\n");
|
||||||
|
printf(" version of Nagios, you should be aware that some variables/definitions\n");
|
||||||
|
printf(" may have been removed or modified in this version. Make sure to read\n");
|
||||||
|
printf(" the HTML documentation regarding the config files, as well as the\n");
|
||||||
|
printf(" 'Whats New' section to find out what has changed.\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up after ourselves */
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
/* free config_file */
|
||||||
|
my_free(config_file);
|
||||||
|
|
||||||
|
/* exit */
|
||||||
|
exit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* we're just testing scheduling... */
|
||||||
|
else if(test_scheduling == TRUE) {
|
||||||
|
|
||||||
|
/* reset program variables */
|
||||||
|
reset_variables();
|
||||||
|
|
||||||
|
/* read in the configuration files (main config file and all host config files) */
|
||||||
|
result = read_main_config_file(config_file);
|
||||||
|
|
||||||
|
/* drop privileges */
|
||||||
|
if(result == OK)
|
||||||
|
if((result = drop_privileges(nagios_user, nagios_group)) == ERROR)
|
||||||
|
printf("Failed to drop privileges. Aborting.");
|
||||||
|
|
||||||
|
/* read object config files */
|
||||||
|
if(result == OK)
|
||||||
|
result = read_all_object_data(config_file);
|
||||||
|
|
||||||
|
/* read initial service and host state information */
|
||||||
|
if(result == OK) {
|
||||||
|
initialize_retention_data(config_file);
|
||||||
|
read_initial_state_information();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result != OK)
|
||||||
|
printf("***> One or more problems was encountered while reading configuration data...\n");
|
||||||
|
|
||||||
|
/* run the pre-flight check to make sure everything looks okay */
|
||||||
|
if(result == OK) {
|
||||||
|
if((result = pre_flight_check()) != OK)
|
||||||
|
printf("***> One or more problems was encountered while running the pre-flight check...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result == OK) {
|
||||||
|
|
||||||
|
/* initialize the event timing loop */
|
||||||
|
init_timing_loop();
|
||||||
|
|
||||||
|
/* display scheduling information */
|
||||||
|
display_scheduling_info();
|
||||||
|
|
||||||
|
if(precache_objects == TRUE) {
|
||||||
|
printf("\n");
|
||||||
|
printf("OBJECT PRECACHING\n");
|
||||||
|
printf("-----------------\n");
|
||||||
|
printf("Object config files were precached.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef TEST_TIMEPERIODS
|
||||||
|
#ifdef TEST_TIMEPERIODS
|
||||||
|
/* DO SOME TIMEPERIOD TESTING - ADDED 08/11/2009 */
|
||||||
|
time_t now, pref_time, valid_time;
|
||||||
|
timeperiod *tp;
|
||||||
|
tp = find_timeperiod("247_exclusion");
|
||||||
|
time(&now);
|
||||||
|
pref_time = now;
|
||||||
|
get_next_valid_time(pref_time, &valid_time, tp);
|
||||||
|
printf("=====\n");
|
||||||
|
printf("CURRENT: %lu = %s", (unsigned long)now, ctime(&now));
|
||||||
|
printf("PREFERRED: %lu = %s", (unsigned long)pref_time, ctime(&pref_time));
|
||||||
|
printf("NEXT: %lu = %s", (unsigned long)valid_time, ctime(&valid_time));
|
||||||
|
printf("=====\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clean up after ourselves */
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
/* exit */
|
||||||
|
exit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* else start to monitor things... */
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* keep monitoring things until we get a shutdown command */
|
||||||
|
do {
|
||||||
|
|
||||||
|
/* reset program variables */
|
||||||
|
reset_variables();
|
||||||
|
|
||||||
|
/* get PID */
|
||||||
|
nagios_pid = (int)getpid();
|
||||||
|
|
||||||
|
/* read in the configuration files (main and resource config files) */
|
||||||
|
result = read_main_config_file(config_file);
|
||||||
|
|
||||||
|
/* NOTE 11/06/07 EG moved to after we read config files, as user may have overridden timezone offset */
|
||||||
|
/* get program (re)start time and save as macro */
|
||||||
|
program_start = time(NULL);
|
||||||
|
my_free(mac->x[MACRO_PROCESSSTARTTIME]);
|
||||||
|
asprintf(&mac->x[MACRO_PROCESSSTARTTIME], "%lu", (unsigned long)program_start);
|
||||||
|
|
||||||
|
/* open debug log */
|
||||||
|
open_debug_log();
|
||||||
|
|
||||||
|
/* drop privileges */
|
||||||
|
if(drop_privileges(nagios_user, nagios_group) == ERROR) {
|
||||||
|
|
||||||
|
logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Failed to drop privileges. Aborting.");
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
exit(ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* initialize modules */
|
||||||
|
neb_init_modules();
|
||||||
|
neb_init_callback_list();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* this must be logged after we read config data, as user may have changed location of main log file */
|
||||||
|
logit(NSLOG_PROCESS_INFO, TRUE, "Nagios %s starting... (PID=%d)\n", PROGRAM_VERSION, (int)getpid());
|
||||||
|
|
||||||
|
/* log the local time - may be different than clock time due to timezone offset */
|
||||||
|
now = time(NULL);
|
||||||
|
tm = localtime_r(&now, &tm_s);
|
||||||
|
strftime(datestring, sizeof(datestring), "%a %b %d %H:%M:%S %Z %Y", tm);
|
||||||
|
logit(NSLOG_PROCESS_INFO, TRUE, "Local time is %s", datestring);
|
||||||
|
|
||||||
|
/* write log version/info */
|
||||||
|
write_log_file_info(NULL);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* load modules */
|
||||||
|
neb_load_all_modules();
|
||||||
|
|
||||||
|
/* send program data to broker */
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_PRELAUNCH, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* read in all object config data */
|
||||||
|
if(result == OK)
|
||||||
|
result = read_all_object_data(config_file);
|
||||||
|
|
||||||
|
/* there was a problem reading the config files */
|
||||||
|
if(result != OK)
|
||||||
|
logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Bailing out due to one or more errors encountered in the configuration files. Run Nagios from the command line with the -v option to verify your config before restarting. (PID=%d)", (int)getpid());
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* run the pre-flight check to make sure everything looks okay*/
|
||||||
|
if((result = pre_flight_check()) != OK)
|
||||||
|
logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_VERIFICATION_ERROR, TRUE, "Bailing out due to errors encountered while running the pre-flight check. Run Nagios from the command line with the -v option to verify your config before restarting. (PID=%d)\n", (int)getpid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* an error occurred that prevented us from (re)starting */
|
||||||
|
if(result != OK) {
|
||||||
|
|
||||||
|
/* if we were restarting, we need to cleanup from the previous run */
|
||||||
|
if(sigrestart == TRUE) {
|
||||||
|
|
||||||
|
/* clean up the status data */
|
||||||
|
cleanup_status_data(config_file, TRUE);
|
||||||
|
|
||||||
|
/* shutdown the external command worker thread */
|
||||||
|
shutdown_command_file_worker_thread();
|
||||||
|
|
||||||
|
/* close and delete the external command file FIFO */
|
||||||
|
close_command_file();
|
||||||
|
|
||||||
|
/* cleanup embedded perl interpreter */
|
||||||
|
if(embedded_perl_initialized == TRUE)
|
||||||
|
deinit_embedded_perl();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send program data to broker */
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL, NULL);
|
||||||
|
#endif
|
||||||
|
cleanup();
|
||||||
|
exit(ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* initialize embedded Perl interpreter */
|
||||||
|
/* NOTE 02/15/08 embedded Perl must be initialized if compiled in, regardless of whether or not its enabled in the config file */
|
||||||
|
/* It compiled it, but not initialized, Nagios will segfault in readdir() calls, as libperl takes this function over */
|
||||||
|
if(embedded_perl_initialized == FALSE) {
|
||||||
|
/* if(enable_embedded_perl==TRUE){*/
|
||||||
|
#ifdef EMBEDDEDPERL
|
||||||
|
init_embedded_perl(env);
|
||||||
|
#else
|
||||||
|
init_embedded_perl(NULL);
|
||||||
|
#endif
|
||||||
|
embedded_perl_initialized = TRUE;
|
||||||
|
/* }*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle signals (interrupts) */
|
||||||
|
setup_sighandler();
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send program data to broker */
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_START, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* enter daemon mode (unless we're restarting...) */
|
||||||
|
if(daemon_mode == TRUE && sigrestart == FALSE) {
|
||||||
|
|
||||||
|
result = daemon_init();
|
||||||
|
|
||||||
|
/* we had an error daemonizing, so bail... */
|
||||||
|
if(result == ERROR) {
|
||||||
|
logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid());
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send program data to broker */
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL, NULL);
|
||||||
|
#endif
|
||||||
|
cleanup();
|
||||||
|
exit(ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
asprintf(&buffer, "Finished daemonizing... (New PID=%d)\n", (int)getpid());
|
||||||
|
write_to_all_logs(buffer, NSLOG_PROCESS_INFO);
|
||||||
|
my_free(buffer);
|
||||||
|
|
||||||
|
/* get new PID */
|
||||||
|
nagios_pid = (int)getpid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open the command file (named pipe) for reading */
|
||||||
|
result = open_command_file();
|
||||||
|
if(result != OK) {
|
||||||
|
|
||||||
|
logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to errors encountered while trying to initialize the external command file... (PID=%d)\n", (int)getpid());
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send program data to broker */
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_PROCESS_INITIATED, NEBATTR_SHUTDOWN_ABNORMAL, NULL);
|
||||||
|
#endif
|
||||||
|
cleanup();
|
||||||
|
exit(ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize status data unless we're starting */
|
||||||
|
if(sigrestart == FALSE)
|
||||||
|
initialize_status_data(config_file);
|
||||||
|
|
||||||
|
/* read initial service and host state information */
|
||||||
|
initialize_retention_data(config_file);
|
||||||
|
read_initial_state_information();
|
||||||
|
|
||||||
|
/* initialize comment data */
|
||||||
|
initialize_comment_data(config_file);
|
||||||
|
|
||||||
|
/* initialize scheduled downtime data */
|
||||||
|
initialize_downtime_data(config_file);
|
||||||
|
|
||||||
|
/* initialize performance data */
|
||||||
|
initialize_performance_data(config_file);
|
||||||
|
|
||||||
|
/* Determine which checks are still executing so they are not
|
||||||
|
scheduled when the timing loop is initialized */
|
||||||
|
find_executing_checks(check_result_path);
|
||||||
|
|
||||||
|
/* initialize the event timing loop */
|
||||||
|
init_timing_loop();
|
||||||
|
|
||||||
|
/* initialize check statistics */
|
||||||
|
init_check_stats();
|
||||||
|
|
||||||
|
/* check for updates */
|
||||||
|
check_for_nagios_updates(FALSE, TRUE);
|
||||||
|
|
||||||
|
/* update all status data (with retained information) */
|
||||||
|
update_all_status_data();
|
||||||
|
|
||||||
|
/* log initial host and service state */
|
||||||
|
log_host_states(INITIAL_STATES, NULL);
|
||||||
|
log_service_states(INITIAL_STATES, NULL);
|
||||||
|
|
||||||
|
/* reset the restart flag */
|
||||||
|
sigrestart = FALSE;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send program data to broker */
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_EVENTLOOPSTART, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get event start time and save as macro */
|
||||||
|
event_start = time(NULL);
|
||||||
|
my_free(mac->x[MACRO_EVENTSTARTTIME]);
|
||||||
|
asprintf(&mac->x[MACRO_EVENTSTARTTIME], "%lu", (unsigned long)event_start);
|
||||||
|
|
||||||
|
/***** start monitoring all services *****/
|
||||||
|
/* (doesn't return until a restart or shutdown signal is encountered) */
|
||||||
|
event_execution_loop();
|
||||||
|
|
||||||
|
/* 03/01/2007 EG Moved from sighandler() to prevent FUTEX locking problems under NPTL */
|
||||||
|
/* 03/21/2007 EG SIGSEGV signals are still logged in sighandler() so we don't loose them */
|
||||||
|
/* did we catch a signal? */
|
||||||
|
if(caught_signal == TRUE) {
|
||||||
|
|
||||||
|
if(sig_id == SIGHUP)
|
||||||
|
asprintf(&buffer, "Caught SIGHUP, restarting...\n");
|
||||||
|
else if(sig_id != SIGSEGV)
|
||||||
|
asprintf(&buffer, "Caught SIG%s, shutting down...\n", sigs[sig_id]);
|
||||||
|
|
||||||
|
write_to_all_logs(buffer, NSLOG_PROCESS_INFO);
|
||||||
|
my_free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send program data to broker */
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_EVENTLOOPEND, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
if(sigshutdown == TRUE)
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_SHUTDOWN, NEBFLAG_USER_INITIATED, NEBATTR_SHUTDOWN_NORMAL, NULL);
|
||||||
|
else if(sigrestart == TRUE)
|
||||||
|
broker_program_state(NEBTYPE_PROCESS_RESTART, NEBFLAG_USER_INITIATED, NEBATTR_RESTART_NORMAL, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* save service and host state information */
|
||||||
|
save_state_information(FALSE);
|
||||||
|
cleanup_retention_data(config_file);
|
||||||
|
|
||||||
|
/* clean up performance data */
|
||||||
|
cleanup_performance_data(config_file);
|
||||||
|
|
||||||
|
/* clean up the scheduled downtime data */
|
||||||
|
cleanup_downtime_data(config_file);
|
||||||
|
|
||||||
|
/* clean up the comment data */
|
||||||
|
cleanup_comment_data(config_file);
|
||||||
|
|
||||||
|
/* clean up the status data unless we're restarting */
|
||||||
|
if(sigrestart == FALSE)
|
||||||
|
cleanup_status_data(config_file, TRUE);
|
||||||
|
|
||||||
|
/* close and delete the external command file FIFO unless we're restarting */
|
||||||
|
if(sigrestart == FALSE) {
|
||||||
|
shutdown_command_file_worker_thread();
|
||||||
|
close_command_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cleanup embedded perl interpreter */
|
||||||
|
if(sigrestart == FALSE)
|
||||||
|
deinit_embedded_perl();
|
||||||
|
|
||||||
|
/* shutdown stuff... */
|
||||||
|
if(sigshutdown == TRUE) {
|
||||||
|
|
||||||
|
/* make sure lock file has been removed - it may not have been if we received a shutdown command */
|
||||||
|
if(daemon_mode == TRUE)
|
||||||
|
unlink(lock_file);
|
||||||
|
|
||||||
|
/* log a shutdown message */
|
||||||
|
logit(NSLOG_PROCESS_INFO, TRUE, "Successfully shutdown... (PID=%d)\n", (int)getpid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up after ourselves */
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
/* close debug log */
|
||||||
|
close_debug_log();
|
||||||
|
|
||||||
|
}
|
||||||
|
while(sigrestart == TRUE && sigshutdown == FALSE);
|
||||||
|
|
||||||
|
/* free misc memory */
|
||||||
|
my_free(config_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
1778
base/nagiostats.c
Normal file
640
base/nebmods.c
Normal file
@ -0,0 +1,640 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* NEBMODS.C - Event Broker Module Functions
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2008 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 11-02-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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/nebmods.h"
|
||||||
|
#include "../include/neberrors.h"
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
|
||||||
|
|
||||||
|
nebmodule *neb_module_list = NULL;
|
||||||
|
nebcallback **neb_callback_list = NULL;
|
||||||
|
|
||||||
|
extern char *temp_path;
|
||||||
|
|
||||||
|
|
||||||
|
/*#define DEBUG*/
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
/* INITIALIZATION/CLEANUP FUNCTIONS */
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/* initialize module routines */
|
||||||
|
int neb_init_modules(void) {
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
int result = OK;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* initialize library */
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
result = lt_dlinit();
|
||||||
|
if(result)
|
||||||
|
return ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deinitialize module routines */
|
||||||
|
int neb_deinit_modules(void) {
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
int result = OK;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* deinitialize library */
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
result = lt_dlexit();
|
||||||
|
if(result)
|
||||||
|
return ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* add a new module to module list */
|
||||||
|
int neb_add_module(char *filename, char *args, int should_be_loaded) {
|
||||||
|
nebmodule *new_module = NULL;
|
||||||
|
int x = OK;
|
||||||
|
|
||||||
|
if(filename == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* allocate memory */
|
||||||
|
new_module = (nebmodule *)malloc(sizeof(nebmodule));
|
||||||
|
if(new_module == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* initialize vars */
|
||||||
|
new_module->filename = (char *)strdup(filename);
|
||||||
|
new_module->args = (args == NULL) ? NULL : (char *)strdup(args);
|
||||||
|
new_module->should_be_loaded = should_be_loaded;
|
||||||
|
new_module->is_currently_loaded = FALSE;
|
||||||
|
for(x = 0; x < NEBMODULE_MODINFO_NUMITEMS; x++)
|
||||||
|
new_module->info[x] = NULL;
|
||||||
|
new_module->module_handle = NULL;
|
||||||
|
new_module->init_func = NULL;
|
||||||
|
new_module->deinit_func = NULL;
|
||||||
|
#ifdef HAVE_PTHREAD_H
|
||||||
|
new_module->thread_id = (pthread_t)NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* add module to head of list */
|
||||||
|
new_module->next = neb_module_list;
|
||||||
|
neb_module_list = new_module;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTBROKER, 0, "Added module: name='%s', args='%s', should_be_loaded='%d'\n", filename, args, should_be_loaded);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* free memory allocated to module list */
|
||||||
|
int neb_free_module_list(void) {
|
||||||
|
nebmodule *temp_module = NULL;
|
||||||
|
nebmodule *next_module = NULL;
|
||||||
|
int x = OK;
|
||||||
|
|
||||||
|
for(temp_module = neb_module_list; temp_module;) {
|
||||||
|
next_module = temp_module->next;
|
||||||
|
my_free(temp_module->filename);
|
||||||
|
my_free(temp_module->args);
|
||||||
|
for(x = 0; x < NEBMODULE_MODINFO_NUMITEMS; x++)
|
||||||
|
my_free(temp_module->info[x]);
|
||||||
|
my_free(temp_module);
|
||||||
|
temp_module = next_module;
|
||||||
|
}
|
||||||
|
|
||||||
|
neb_module_list = NULL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
/* LOAD/UNLOAD FUNCTIONS */
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* load all modules */
|
||||||
|
int neb_load_all_modules(void) {
|
||||||
|
nebmodule *temp_module = NULL;
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
for(temp_module = neb_module_list; temp_module; temp_module = temp_module->next) {
|
||||||
|
result = neb_load_module(temp_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
# define PATH_MAX 4096
|
||||||
|
#endif
|
||||||
|
/* load a particular module */
|
||||||
|
int neb_load_module(nebmodule *mod) {
|
||||||
|
int (*initfunc)(int, char *, void *);
|
||||||
|
int *module_version_ptr = NULL;
|
||||||
|
char output_file[PATH_MAX];
|
||||||
|
int dest_fd, result = OK;
|
||||||
|
|
||||||
|
if(mod == NULL || mod->filename == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* don't reopen the module */
|
||||||
|
if(mod->is_currently_loaded == TRUE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* don't load modules unless they should be loaded */
|
||||||
|
if(mod->should_be_loaded == FALSE)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/**********
|
||||||
|
Using dlopen() is great, but a real danger as-is. The problem with loaded modules is that if you overwrite the original file (e.g. using 'mv'),
|
||||||
|
you do not alter the inode of the original file. Since the original file/module is memory-mapped in some fashion, Nagios will segfault the next
|
||||||
|
time an event broker call is directed to one of the module's callback functions. This is extremely problematic when it comes to upgrading NEB
|
||||||
|
modules while Nagios is running. A workaround is to (1) 'mv' the original/loaded module file to another name (on the same filesystem)
|
||||||
|
and (2) copy the new module file to the location of the original one (using the original filename). In this scenario, dlopen() will keep referencing
|
||||||
|
the original file/inode for callbacks. This is not an ideal solution. A better one is to delete the module file once it is loaded by dlopen().
|
||||||
|
This prevents other processed from unintentially overwriting the original file, which would cause Nagios to crash. However, if we delete the file
|
||||||
|
before anyone else can muck with it, things should be good. 'lsof' shows that a deleted file is still referenced by the kernel and callback
|
||||||
|
functions continue to work once the module has been loaded. Long story, but this took quite a while to figure out, as there isn't much
|
||||||
|
of anything I could find on the subject other than some sketchy info on similar problems on HP-UX. Hopefully this will save future coders some time.
|
||||||
|
So... the trick is to (1) copy the module to a temp file, (2) dlopen() the temp file, and (3) immediately delete the temp file.
|
||||||
|
************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* open a temp file for copying the module. We use my_fdcopy() so
|
||||||
|
* we re-use the destination file descriptor returned by mkstemp(3),
|
||||||
|
* which we have to close ourselves.
|
||||||
|
*/
|
||||||
|
snprintf(output_file, sizeof(output_file) - 1, "%s/nebmodXXXXXX", temp_path);
|
||||||
|
dest_fd = mkstemp(output_file);
|
||||||
|
result = my_fdcopy(mod->filename, output_file, dest_fd);
|
||||||
|
close(dest_fd);
|
||||||
|
if(result == ERROR) {
|
||||||
|
logit(NSLOG_RUNTIME_ERROR, FALSE, "Error: Failed to safely copy module '%s'. The module will not be loaded\n", mod->filename);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* load the module (use the temp copy we just made) */
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
mod->module_handle = lt_dlopen(output_file);
|
||||||
|
#else
|
||||||
|
mod->module_handle = (void *)dlopen(output_file, RTLD_NOW | RTLD_GLOBAL);
|
||||||
|
#endif
|
||||||
|
if(mod->module_handle == NULL) {
|
||||||
|
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
logit(NSLOG_RUNTIME_ERROR, FALSE, "Error: Could not load module '%s' -> %s\n", mod->filename, lt_dlerror());
|
||||||
|
#else
|
||||||
|
logit(NSLOG_RUNTIME_ERROR, FALSE, "Error: Could not load module '%s' -> %s\n", mod->filename, dlerror());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mark the module as being loaded */
|
||||||
|
mod->is_currently_loaded = TRUE;
|
||||||
|
|
||||||
|
/* delete the temp copy of the module we just created and loaded */
|
||||||
|
/* this will prevent other processes from overwriting the file (using the same inode), which would cause Nagios to crash */
|
||||||
|
/* the kernel will keep the deleted file in memory until we unload it */
|
||||||
|
/* NOTE: This *should* be portable to most Unices, but I've only tested it on Linux */
|
||||||
|
if(unlink(output_file) == -1) {
|
||||||
|
logit(NSLOG_RUNTIME_ERROR, FALSE, "Error: Could not delete temporary file '%s' used for module '%s'. The module will be unloaded: %s\n", output_file, mod->filename, strerror(errno));
|
||||||
|
neb_unload_module(mod, NEBMODULE_FORCE_UNLOAD, NEBMODULE_ERROR_API_VERSION);
|
||||||
|
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find module API version */
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
module_version_ptr = (int *)lt_dlsym(mod->module_handle, "__neb_api_version");
|
||||||
|
#else
|
||||||
|
module_version_ptr = (int *)dlsym(mod->module_handle, "__neb_api_version");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check the module API version */
|
||||||
|
if(module_version_ptr == NULL || ((*module_version_ptr) != CURRENT_NEB_API_VERSION)) {
|
||||||
|
|
||||||
|
logit(NSLOG_RUNTIME_ERROR, FALSE, "Error: Module '%s' is using an old or unspecified version of the event broker API. Module will be unloaded.\n", mod->filename);
|
||||||
|
|
||||||
|
neb_unload_module(mod, NEBMODULE_FORCE_UNLOAD, NEBMODULE_ERROR_API_VERSION);
|
||||||
|
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* locate the initialization function */
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
mod->init_func = lt_dlsym(mod->module_handle, "nebmodule_init");
|
||||||
|
#else
|
||||||
|
mod->init_func = (void *)dlsym(mod->module_handle, "nebmodule_init");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* if the init function could not be located, unload the module */
|
||||||
|
if(mod->init_func == NULL) {
|
||||||
|
|
||||||
|
logit(NSLOG_RUNTIME_ERROR, FALSE, "Error: Could not locate nebmodule_init() in module '%s'. Module will be unloaded.\n", mod->filename);
|
||||||
|
|
||||||
|
neb_unload_module(mod, NEBMODULE_FORCE_UNLOAD, NEBMODULE_ERROR_NO_INIT);
|
||||||
|
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* run the module's init function */
|
||||||
|
initfunc = mod->init_func;
|
||||||
|
result = (*initfunc)(NEBMODULE_NORMAL_LOAD, mod->args, mod->module_handle);
|
||||||
|
|
||||||
|
/* if the init function returned an error, unload the module */
|
||||||
|
if(result != OK) {
|
||||||
|
|
||||||
|
logit(NSLOG_RUNTIME_ERROR, FALSE, "Error: Function nebmodule_init() in module '%s' returned an error. Module will be unloaded.\n", mod->filename);
|
||||||
|
|
||||||
|
neb_unload_module(mod, NEBMODULE_FORCE_UNLOAD, NEBMODULE_ERROR_BAD_INIT);
|
||||||
|
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
logit(NSLOG_INFO_MESSAGE, FALSE, "Event broker module '%s' initialized successfully.\n", mod->filename);
|
||||||
|
|
||||||
|
/* locate the de-initialization function (may or may not be present) */
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
mod->deinit_func = lt_dlsym(mod->module_handle, "nebmodule_deinit");
|
||||||
|
#else
|
||||||
|
mod->deinit_func = (void *)dlsym(mod->module_handle, "nebmodule_deinit");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTBROKER, 0, "Module '%s' loaded with return code of '%d'\n", mod->filename, result);
|
||||||
|
if(mod->deinit_func != NULL)
|
||||||
|
log_debug_info(DEBUGL_EVENTBROKER, 0, "nebmodule_deinit() found\n");
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* close (unload) all modules that are currently loaded */
|
||||||
|
int neb_unload_all_modules(int flags, int reason) {
|
||||||
|
nebmodule *temp_module;
|
||||||
|
|
||||||
|
for(temp_module = neb_module_list; temp_module; temp_module = temp_module->next) {
|
||||||
|
|
||||||
|
/* skip modules that are not loaded */
|
||||||
|
if(temp_module->is_currently_loaded == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* skip modules that do not have a valid handle */
|
||||||
|
if(temp_module->module_handle == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* close/unload the module */
|
||||||
|
neb_unload_module(temp_module, flags, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* close (unload) a particular module */
|
||||||
|
int neb_unload_module(nebmodule *mod, int flags, int reason) {
|
||||||
|
int (*deinitfunc)(int, int);
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
if(mod == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTBROKER, 0, "Attempting to unload module '%s': flags=%d, reason=%d\n", mod->filename, flags, reason);
|
||||||
|
|
||||||
|
/* call the de-initialization function if available (and the module was initialized) */
|
||||||
|
if(mod->deinit_func && reason != NEBMODULE_ERROR_BAD_INIT) {
|
||||||
|
|
||||||
|
deinitfunc = mod->deinit_func;
|
||||||
|
|
||||||
|
/* module can opt to not be unloaded */
|
||||||
|
result = (*deinitfunc)(flags, reason);
|
||||||
|
|
||||||
|
/* if module doesn't want to be unloaded, exit with error (unless its being forced) */
|
||||||
|
if(result != OK && !(flags & NEBMODULE_FORCE_UNLOAD))
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deregister all of the module's callbacks */
|
||||||
|
neb_deregister_module_callbacks(mod);
|
||||||
|
|
||||||
|
/* unload the module */
|
||||||
|
#ifdef USE_LTDL
|
||||||
|
result = lt_dlclose(mod->module_handle);
|
||||||
|
#else
|
||||||
|
result = dlclose(mod->module_handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* mark the module as being unloaded */
|
||||||
|
mod->is_currently_loaded = FALSE;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTBROKER, 0, "Module '%s' unloaded successfully.\n", mod->filename);
|
||||||
|
|
||||||
|
logit(NSLOG_INFO_MESSAGE, FALSE, "Event broker module '%s' deinitialized successfully.\n", mod->filename);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
/* INFO FUNCTIONS */
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/* sets module information */
|
||||||
|
int neb_set_module_info(void *handle, int type, char *data) {
|
||||||
|
nebmodule *temp_module = NULL;
|
||||||
|
|
||||||
|
if(handle == NULL)
|
||||||
|
return NEBERROR_NOMODULE;
|
||||||
|
|
||||||
|
/* check type */
|
||||||
|
if(type < 0 || type >= NEBMODULE_MODINFO_NUMITEMS)
|
||||||
|
return NEBERROR_MODINFOBOUNDS;
|
||||||
|
|
||||||
|
/* find the module */
|
||||||
|
for(temp_module = neb_module_list; temp_module != NULL; temp_module = temp_module->next) {
|
||||||
|
if((void *)temp_module->module_handle == (void *)handle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(temp_module == NULL)
|
||||||
|
return NEBERROR_BADMODULEHANDLE;
|
||||||
|
|
||||||
|
/* free any previously allocated memory */
|
||||||
|
my_free(temp_module->info[type]);
|
||||||
|
|
||||||
|
/* allocate memory for the new data */
|
||||||
|
if((temp_module->info[type] = (char *)strdup(data)) == NULL)
|
||||||
|
return NEBERROR_NOMEM;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
/* CALLBACK FUNCTIONS */
|
||||||
|
/****************************************************************************/
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/* allows a module to register a callback function */
|
||||||
|
int neb_register_callback(int callback_type, void *mod_handle, int priority, int (*callback_func)(int, void *)) {
|
||||||
|
nebmodule *temp_module = NULL;
|
||||||
|
nebcallback *new_callback = NULL;
|
||||||
|
nebcallback *temp_callback = NULL;
|
||||||
|
nebcallback *last_callback = NULL;
|
||||||
|
|
||||||
|
if(callback_func == NULL)
|
||||||
|
return NEBERROR_NOCALLBACKFUNC;
|
||||||
|
|
||||||
|
if(neb_callback_list == NULL)
|
||||||
|
return NEBERROR_NOCALLBACKLIST;
|
||||||
|
|
||||||
|
if(mod_handle == NULL)
|
||||||
|
return NEBERROR_NOMODULEHANDLE;
|
||||||
|
|
||||||
|
/* make sure the callback type is within bounds */
|
||||||
|
if(callback_type < 0 || callback_type >= NEBCALLBACK_NUMITEMS)
|
||||||
|
return NEBERROR_CALLBACKBOUNDS;
|
||||||
|
|
||||||
|
/* make sure module handle is valid */
|
||||||
|
for(temp_module = neb_module_list; temp_module; temp_module = temp_module->next) {
|
||||||
|
if((void *)temp_module->module_handle == (void *)mod_handle)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(temp_module == NULL)
|
||||||
|
return NEBERROR_BADMODULEHANDLE;
|
||||||
|
|
||||||
|
/* allocate memory */
|
||||||
|
new_callback = (nebcallback *)malloc(sizeof(nebcallback));
|
||||||
|
if(new_callback == NULL)
|
||||||
|
return NEBERROR_NOMEM;
|
||||||
|
|
||||||
|
new_callback->priority = priority;
|
||||||
|
new_callback->module_handle = (void *)mod_handle;
|
||||||
|
new_callback->callback_func = (void *)callback_func;
|
||||||
|
|
||||||
|
/* add new function to callback list, sorted by priority (first come, first served for same priority) */
|
||||||
|
new_callback->next = NULL;
|
||||||
|
if(neb_callback_list[callback_type] == NULL)
|
||||||
|
neb_callback_list[callback_type] = new_callback;
|
||||||
|
else {
|
||||||
|
last_callback = NULL;
|
||||||
|
for(temp_callback = neb_callback_list[callback_type]; temp_callback != NULL; temp_callback = temp_callback->next) {
|
||||||
|
if(temp_callback->priority > new_callback->priority)
|
||||||
|
break;
|
||||||
|
last_callback = temp_callback;
|
||||||
|
}
|
||||||
|
if(last_callback == NULL)
|
||||||
|
neb_callback_list[callback_type] = new_callback;
|
||||||
|
else {
|
||||||
|
if(temp_callback == NULL)
|
||||||
|
last_callback->next = new_callback;
|
||||||
|
else {
|
||||||
|
new_callback->next = temp_callback;
|
||||||
|
last_callback->next = new_callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* dregisters all callback functions for a given module */
|
||||||
|
int neb_deregister_module_callbacks(nebmodule *mod) {
|
||||||
|
nebcallback *temp_callback = NULL;
|
||||||
|
nebcallback *next_callback = NULL;
|
||||||
|
int callback_type = 0;
|
||||||
|
|
||||||
|
if(mod == NULL)
|
||||||
|
return NEBERROR_NOMODULE;
|
||||||
|
|
||||||
|
if(neb_callback_list == NULL)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
for(callback_type = 0; callback_type < NEBCALLBACK_NUMITEMS; callback_type++) {
|
||||||
|
for(temp_callback = neb_callback_list[callback_type]; temp_callback != NULL; temp_callback = next_callback) {
|
||||||
|
next_callback = temp_callback->next;
|
||||||
|
if((void *)temp_callback->module_handle == (void *)mod->module_handle)
|
||||||
|
neb_deregister_callback(callback_type, (int(*)(int, void*))temp_callback->callback_func);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* allows a module to deregister a callback function */
|
||||||
|
int neb_deregister_callback(int callback_type, int (*callback_func)(int, void *)) {
|
||||||
|
nebcallback *temp_callback = NULL;
|
||||||
|
nebcallback *last_callback = NULL;
|
||||||
|
nebcallback *next_callback = NULL;
|
||||||
|
|
||||||
|
if(callback_func == NULL)
|
||||||
|
return NEBERROR_NOCALLBACKFUNC;
|
||||||
|
|
||||||
|
if(neb_callback_list == NULL)
|
||||||
|
return NEBERROR_NOCALLBACKLIST;
|
||||||
|
|
||||||
|
/* make sure the callback type is within bounds */
|
||||||
|
if(callback_type < 0 || callback_type >= NEBCALLBACK_NUMITEMS)
|
||||||
|
return NEBERROR_CALLBACKBOUNDS;
|
||||||
|
|
||||||
|
/* find the callback to remove */
|
||||||
|
for(temp_callback = last_callback = neb_callback_list[callback_type]; temp_callback != NULL; temp_callback = next_callback) {
|
||||||
|
next_callback = temp_callback->next;
|
||||||
|
|
||||||
|
/* we found it */
|
||||||
|
if(temp_callback->callback_func == (void *)callback_func)
|
||||||
|
break;
|
||||||
|
|
||||||
|
last_callback = temp_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we couldn't find the callback */
|
||||||
|
if(temp_callback == NULL)
|
||||||
|
return NEBERROR_CALLBACKNOTFOUND;
|
||||||
|
|
||||||
|
else {
|
||||||
|
/* only one item in the list */
|
||||||
|
if(temp_callback != last_callback->next)
|
||||||
|
neb_callback_list[callback_type] = NULL;
|
||||||
|
else
|
||||||
|
last_callback->next = next_callback;
|
||||||
|
my_free(temp_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* make callbacks to modules */
|
||||||
|
int neb_make_callbacks(int callback_type, void *data) {
|
||||||
|
nebcallback *temp_callback, *next_callback;
|
||||||
|
int (*callbackfunc)(int, void *);
|
||||||
|
register int cbresult = 0;
|
||||||
|
int total_callbacks = 0;
|
||||||
|
|
||||||
|
/* make sure callback list is initialized */
|
||||||
|
if(neb_callback_list == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* make sure the callback type is within bounds */
|
||||||
|
if(callback_type < 0 || callback_type >= NEBCALLBACK_NUMITEMS)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTBROKER, 1, "Making callbacks (type %d)...\n", callback_type);
|
||||||
|
|
||||||
|
/* make the callbacks... */
|
||||||
|
for(temp_callback = neb_callback_list[callback_type]; temp_callback; temp_callback = next_callback) {
|
||||||
|
next_callback = temp_callback->next;
|
||||||
|
callbackfunc = temp_callback->callback_func;
|
||||||
|
cbresult = callbackfunc(callback_type, data);
|
||||||
|
temp_callback = next_callback;
|
||||||
|
|
||||||
|
total_callbacks++;
|
||||||
|
log_debug_info(DEBUGL_EVENTBROKER, 2, "Callback #%d (type %d) return code = %d\n", total_callbacks, callback_type, cbresult);
|
||||||
|
|
||||||
|
/* module wants to cancel callbacks to other modules (and potentially cancel the default Nagios handling of an event) */
|
||||||
|
if(cbresult == NEBERROR_CALLBACKCANCEL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* module wants to override default Nagios handling of an event */
|
||||||
|
/* not sure if we should bail out here just because one module wants to override things - what about other modules? EG 12/11/2006 */
|
||||||
|
else if(cbresult == NEBERROR_CALLBACKOVERRIDE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cbresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* initialize callback list */
|
||||||
|
int neb_init_callback_list(void) {
|
||||||
|
register int x = 0;
|
||||||
|
|
||||||
|
/* allocate memory for the callback list */
|
||||||
|
neb_callback_list = (nebcallback **)malloc(NEBCALLBACK_NUMITEMS * sizeof(nebcallback *));
|
||||||
|
if(neb_callback_list == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* initialize list pointers */
|
||||||
|
for(x = 0; x < NEBCALLBACK_NUMITEMS; x++)
|
||||||
|
neb_callback_list[x] = NULL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* free memory allocated to callback list */
|
||||||
|
int neb_free_callback_list(void) {
|
||||||
|
nebcallback *temp_callback = NULL;
|
||||||
|
nebcallback *next_callback = NULL;
|
||||||
|
register int x = 0;
|
||||||
|
|
||||||
|
if(neb_callback_list == NULL)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
for(x = 0; x < NEBCALLBACK_NUMITEMS; x++) {
|
||||||
|
|
||||||
|
for(temp_callback = neb_callback_list[x]; temp_callback != NULL; temp_callback = next_callback) {
|
||||||
|
next_callback = temp_callback->next;
|
||||||
|
my_free(temp_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
neb_callback_list[x] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_free(neb_callback_list);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
292
base/netutils.c
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* NETUTILS.C - Network connection utility functions for Nagios
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999,2008 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Portions Copyright (c) 1999-2008 Nagios Plugin development team
|
||||||
|
* Last Modified: 12-04-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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/netutils.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* connect to a TCP socket in nonblocking fashion */
|
||||||
|
int my_tcp_connect(char *host_name, int port, int *sd, int timeout) {
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *res;
|
||||||
|
int result;
|
||||||
|
char port_str[6];
|
||||||
|
int flags = 0;
|
||||||
|
fd_set rfds;
|
||||||
|
fd_set wfds;
|
||||||
|
struct timeval tv;
|
||||||
|
int optval;
|
||||||
|
socklen_t optlen;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = PF_INET;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
|
/* make sure our static port_str is long enough */
|
||||||
|
if(port > 65535)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
snprintf(port_str, sizeof(port_str), "%d", port);
|
||||||
|
result = getaddrinfo(host_name, port_str, &hints, &res);
|
||||||
|
if(result != 0) {
|
||||||
|
/*printf("GETADDRINFO: %s (%s) = %s\n",host_name,port_str,gai_strerror(result));*/
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a socket */
|
||||||
|
*sd = socket(res->ai_family, SOCK_STREAM, res->ai_protocol);
|
||||||
|
if(*sd < 0) {
|
||||||
|
freeaddrinfo(res);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make socket non-blocking */
|
||||||
|
flags = fcntl(*sd, F_GETFL, 0);
|
||||||
|
fcntl(*sd, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
|
||||||
|
/* attempt to connect */
|
||||||
|
result = connect(*sd, res->ai_addr, res->ai_addrlen);
|
||||||
|
|
||||||
|
/* immediately successful connect */
|
||||||
|
if(result == 0) {
|
||||||
|
result = OK;
|
||||||
|
/*printf("IMMEDIATE SUCCESS\n");*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* connection error */
|
||||||
|
else if(result < 0 && errno != EINPROGRESS) {
|
||||||
|
result = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* connection in progress - wait for it... */
|
||||||
|
else {
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* set connection timeout */
|
||||||
|
tv.tv_sec = timeout;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(*sd, &wfds);
|
||||||
|
rfds = wfds;
|
||||||
|
|
||||||
|
/* wait for readiness */
|
||||||
|
result = select((*sd) + 1, &rfds, &wfds, NULL, &tv);
|
||||||
|
|
||||||
|
/*printf("SELECT RESULT: %d\n",result);*/
|
||||||
|
|
||||||
|
/* timeout */
|
||||||
|
if(result == 0) {
|
||||||
|
/*printf("TIMEOUT\n");*/
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* an error occurred */
|
||||||
|
if(result < 0 && errno != EINTR) {
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* got something - check it */
|
||||||
|
else if(result > 0) {
|
||||||
|
|
||||||
|
/* get socket options to check for errors */
|
||||||
|
optlen = sizeof(int);
|
||||||
|
if(getsockopt(*sd, SOL_SOCKET, SO_ERROR, (void *)(&optval), &optlen) < 0) {
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* an error occurred in the connection */
|
||||||
|
if(optval != 0) {
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the connection was good! */
|
||||||
|
/*
|
||||||
|
printf("CONNECT SELECT: ERRNO=%s\n",strerror(errno));
|
||||||
|
printf("CONNECT SELECT: OPTVAL=%s\n",strerror(optval));
|
||||||
|
*/
|
||||||
|
result = OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* some other error occurred */
|
||||||
|
else {
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
freeaddrinfo(res);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* based on Beej's sendall - thanks Beej! */
|
||||||
|
int my_sendall(int s, char *buf, int *len, int timeout) {
|
||||||
|
int total_sent = 0;
|
||||||
|
int bytes_left = 0;
|
||||||
|
int n;
|
||||||
|
fd_set wfds;
|
||||||
|
struct timeval tv;
|
||||||
|
int result = OK;
|
||||||
|
time_t start_time;
|
||||||
|
time_t current_time;
|
||||||
|
|
||||||
|
time(&start_time);
|
||||||
|
|
||||||
|
bytes_left = *len;
|
||||||
|
while(total_sent < *len) {
|
||||||
|
|
||||||
|
/* set send timeout */
|
||||||
|
tv.tv_sec = timeout;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(s, &wfds);
|
||||||
|
|
||||||
|
/* wait for readiness */
|
||||||
|
result = select(s + 1, NULL, &wfds, NULL, &tv);
|
||||||
|
|
||||||
|
/* timeout */
|
||||||
|
if(result == 0) {
|
||||||
|
/*printf("RECV SELECT TIMEOUT\n");*/
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* error */
|
||||||
|
else if(result < 0) {
|
||||||
|
/*printf("RECV SELECT ERROR: %s\n",strerror(errno));*/
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we're ready to write some data */
|
||||||
|
result = OK;
|
||||||
|
|
||||||
|
/* send the data */
|
||||||
|
n = send(s, buf + total_sent, bytes_left, 0);
|
||||||
|
if(n == -1) {
|
||||||
|
/*printf("SEND ERROR: (%d) %s\n",s,strerror(errno));*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_sent += n;
|
||||||
|
bytes_left -= n;
|
||||||
|
|
||||||
|
/* make sure we haven't overrun the timeout */
|
||||||
|
time(¤t_time);
|
||||||
|
if(current_time - start_time > timeout) {
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = total_sent;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* receives all data in non-blocking mode with a timeout - modelled after sendall() */
|
||||||
|
int my_recvall(int s, char *buf, int *len, int timeout) {
|
||||||
|
int total_received = 0;
|
||||||
|
int bytes_left = *len;
|
||||||
|
int n = 0;
|
||||||
|
time_t start_time;
|
||||||
|
time_t current_time;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/* clear the receive buffer */
|
||||||
|
bzero(buf, *len);
|
||||||
|
|
||||||
|
time(&start_time);
|
||||||
|
|
||||||
|
/* receive all data */
|
||||||
|
while(total_received < *len) {
|
||||||
|
|
||||||
|
/* set receive timeout */
|
||||||
|
tv.tv_sec = timeout;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(s, &rfds);
|
||||||
|
|
||||||
|
/* wait for readiness */
|
||||||
|
result = select(s + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
/* timeout */
|
||||||
|
if(result == 0) {
|
||||||
|
/*printf("RECV SELECT TIMEOUT\n");*/
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* error */
|
||||||
|
else if(result < 0) {
|
||||||
|
/*printf("RECV SELECT ERROR: %s\n",strerror(errno));*/
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we're ready to read some data */
|
||||||
|
result = OK;
|
||||||
|
|
||||||
|
/* receive some data */
|
||||||
|
n = recv(s, buf + total_received, bytes_left, 0);
|
||||||
|
|
||||||
|
/* server disconnected */
|
||||||
|
if(n == 0) {
|
||||||
|
/*printf("SERVER DISCONNECT\n");*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply bytes we received */
|
||||||
|
total_received += n;
|
||||||
|
bytes_left -= n;
|
||||||
|
|
||||||
|
/* make sure we haven't overrun the timeout */
|
||||||
|
time(¤t_time);
|
||||||
|
if(current_time - start_time > timeout) {
|
||||||
|
result = ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return number of bytes actually received here */
|
||||||
|
*len = total_received;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
2170
base/notifications.c
Normal file
116
base/perfdata.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* PERFDATA.C - Performance data routines for Nagios
|
||||||
|
*
|
||||||
|
* Copyright (c) 2000-2004 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 11-29-2004
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*********** COMMON HEADER FILES ***********/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
#include "../include/perfdata.h"
|
||||||
|
#include "../include/macros.h"
|
||||||
|
|
||||||
|
/***** IMPLEMENTATION-SPECIFIC HEADER FILES *****/
|
||||||
|
|
||||||
|
#ifdef USE_XPDDEFAULT
|
||||||
|
#include "../xdata/xpddefault.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern int process_performance_data;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/************** INITIALIZATION & CLEANUP FUNCTIONS ****************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* initializes performance data */
|
||||||
|
int initialize_performance_data(char *config_file) {
|
||||||
|
|
||||||
|
#ifdef USE_XPDDEFAULT
|
||||||
|
xpddefault_initialize_performance_data(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* cleans up performance data */
|
||||||
|
int cleanup_performance_data(char *config_file) {
|
||||||
|
|
||||||
|
#ifdef USE_XPDDEFAULT
|
||||||
|
xpddefault_cleanup_performance_data(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/****************** PERFORMANCE DATA FUNCTIONS ********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* updates service performance data */
|
||||||
|
int update_service_performance_data(service *svc) {
|
||||||
|
|
||||||
|
/* should we be processing performance data for anything? */
|
||||||
|
if(process_performance_data == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* should we process performance data for this service? */
|
||||||
|
if(svc->process_performance_data == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* process the performance data! */
|
||||||
|
#ifdef USE_XPDDEFAULT
|
||||||
|
xpddefault_update_service_performance_data(svc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* updates host performance data */
|
||||||
|
int update_host_performance_data(host *hst) {
|
||||||
|
|
||||||
|
/* should we be processing performance data for anything? */
|
||||||
|
if(process_performance_data == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* should we process performance data for this host? */
|
||||||
|
if(hst->process_performance_data == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* process the performance data! */
|
||||||
|
#ifdef USE_XPDDEFAULT
|
||||||
|
xpddefault_update_host_performance_data(hst);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
700
base/sehandlers.c
Normal file
@ -0,0 +1,700 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* SEHANDLERS.C - Service and host event and state handlers for Nagios
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2010 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 08-05-2010
|
||||||
|
*
|
||||||
|
* 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 "../include/config.h"
|
||||||
|
#include "../include/comments.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/statusdata.h"
|
||||||
|
#include "../include/downtime.h"
|
||||||
|
#include "../include/macros.h"
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
#include "../include/perfdata.h"
|
||||||
|
#include "../include/broker.h"
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
#include "../include/neberrors.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int enable_event_handlers;
|
||||||
|
extern int obsess_over_services;
|
||||||
|
extern int obsess_over_hosts;
|
||||||
|
|
||||||
|
extern int log_event_handlers;
|
||||||
|
|
||||||
|
extern unsigned long next_event_id;
|
||||||
|
extern unsigned long next_problem_id;
|
||||||
|
|
||||||
|
extern int event_handler_timeout;
|
||||||
|
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 *ocsp_command;
|
||||||
|
extern char *ochp_command;
|
||||||
|
extern command *ocsp_command_ptr;
|
||||||
|
extern command *ochp_command_ptr;
|
||||||
|
|
||||||
|
extern time_t program_start;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/************* OBSESSIVE COMPULSIVE HANDLER FUNCTIONS *************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* handles service check results in an obsessive compulsive manner... */
|
||||||
|
int obsessive_compulsive_service_check_processor(service *svc) {
|
||||||
|
char *raw_command = NULL;
|
||||||
|
char *processed_command = NULL;
|
||||||
|
host *temp_host = NULL;
|
||||||
|
int early_timeout = FALSE;
|
||||||
|
double exectime = 0.0;
|
||||||
|
int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;
|
||||||
|
nagios_macros mac;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "obsessive_compulsive_service_check_processor()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* bail out if we shouldn't be obsessing */
|
||||||
|
if(obsess_over_services == FALSE)
|
||||||
|
return OK;
|
||||||
|
if(svc->obsess_over_service == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* if there is no valid command, exit */
|
||||||
|
if(ocsp_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* find the associated host */
|
||||||
|
if((temp_host = (host *)svc->host_ptr) == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* update service macros */
|
||||||
|
memset(&mac, 0, sizeof(mac));
|
||||||
|
grab_host_macros_r(&mac, temp_host);
|
||||||
|
grab_service_macros_r(&mac, svc);
|
||||||
|
|
||||||
|
/* get the raw command line */
|
||||||
|
get_raw_command_line_r(&mac, ocsp_command_ptr, ocsp_command, &raw_command, macro_options);
|
||||||
|
if(raw_command == NULL) {
|
||||||
|
clear_volatile_macros_r(&mac);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_CHECKS, 2, "Raw obsessive compulsive service processor command line: %s\n", raw_command);
|
||||||
|
|
||||||
|
/* process any macros in the raw command line */
|
||||||
|
process_macros_r(&mac, raw_command, &processed_command, macro_options);
|
||||||
|
my_free(raw_command);
|
||||||
|
if(processed_command == NULL) {
|
||||||
|
clear_volatile_macros_r(&mac);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_CHECKS, 2, "Processed obsessive compulsive service processor command line: %s\n", processed_command);
|
||||||
|
|
||||||
|
/* run the command */
|
||||||
|
my_system_r(&mac, processed_command, ocsp_timeout, &early_timeout, &exectime, NULL, 0);
|
||||||
|
|
||||||
|
clear_volatile_macros_r(&mac);
|
||||||
|
|
||||||
|
/* check to see if the command timed out */
|
||||||
|
if(early_timeout == TRUE)
|
||||||
|
logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: OCSP command '%s' for service '%s' on host '%s' timed out after %d seconds\n", processed_command, svc->description, svc->host_name, ocsp_timeout);
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(processed_command);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* handles host check results in an obsessive compulsive manner... */
|
||||||
|
int obsessive_compulsive_host_check_processor(host *hst) {
|
||||||
|
char *raw_command = NULL;
|
||||||
|
char *processed_command = NULL;
|
||||||
|
int early_timeout = FALSE;
|
||||||
|
double exectime = 0.0;
|
||||||
|
int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;
|
||||||
|
nagios_macros mac;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "obsessive_compulsive_host_check_processor()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* bail out if we shouldn't be obsessing */
|
||||||
|
if(obsess_over_hosts == FALSE)
|
||||||
|
return OK;
|
||||||
|
if(hst->obsess_over_host == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* if there is no valid command, exit */
|
||||||
|
if(ochp_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* update macros */
|
||||||
|
memset(&mac, 0, sizeof(mac));
|
||||||
|
grab_host_macros_r(&mac, hst);
|
||||||
|
|
||||||
|
/* get the raw command line */
|
||||||
|
get_raw_command_line_r(&mac, ochp_command_ptr, ochp_command, &raw_command, macro_options);
|
||||||
|
if(raw_command == NULL) {
|
||||||
|
clear_volatile_macros_r(&mac);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_CHECKS, 2, "Raw obsessive compulsive host processor command line: %s\n", raw_command);
|
||||||
|
|
||||||
|
/* process any macros in the raw command line */
|
||||||
|
process_macros_r(&mac, raw_command, &processed_command, macro_options);
|
||||||
|
my_free(raw_command);
|
||||||
|
if(processed_command == NULL) {
|
||||||
|
clear_volatile_macros_r(&mac);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_CHECKS, 2, "Processed obsessive compulsive host processor command line: %s\n", processed_command);
|
||||||
|
|
||||||
|
/* run the command */
|
||||||
|
my_system_r(&mac, processed_command, ochp_timeout, &early_timeout, &exectime, NULL, 0);
|
||||||
|
clear_volatile_macros_r(&mac);
|
||||||
|
|
||||||
|
/* check to see if the command timed out */
|
||||||
|
if(early_timeout == TRUE)
|
||||||
|
logit(NSLOG_RUNTIME_WARNING, TRUE, "Warning: OCHP command '%s' for host '%s' timed out after %d seconds\n", processed_command, hst->name, ochp_timeout);
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(processed_command);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/**************** SERVICE EVENT HANDLER FUNCTIONS *****************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* handles changes in the state of a service */
|
||||||
|
int handle_service_event(service *svc) {
|
||||||
|
host *temp_host = NULL;
|
||||||
|
nagios_macros mac;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_service_event()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
broker_statechange_data(NEBTYPE_STATECHANGE_END, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_STATECHANGE, (void *)svc, svc->current_state, svc->state_type, svc->current_attempt, svc->max_attempts, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* bail out if we shouldn't be running event handlers */
|
||||||
|
if(enable_event_handlers == FALSE)
|
||||||
|
return OK;
|
||||||
|
if(svc->event_handler_enabled == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* find the host */
|
||||||
|
if((temp_host = (host *)svc->host_ptr) == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* update service macros */
|
||||||
|
memset(&mac, 0, sizeof(mac));
|
||||||
|
grab_host_macros_r(&mac, temp_host);
|
||||||
|
grab_service_macros_r(&mac, svc);
|
||||||
|
|
||||||
|
/* run the global service event handler */
|
||||||
|
run_global_service_event_handler(&mac, svc);
|
||||||
|
|
||||||
|
/* run the event handler command if there is one */
|
||||||
|
if(svc->event_handler != NULL)
|
||||||
|
run_service_event_handler(&mac, svc);
|
||||||
|
clear_volatile_macros_r(&mac);
|
||||||
|
|
||||||
|
/* check for external commands - the event handler may have given us some directives... */
|
||||||
|
check_for_external_commands();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* runs the global service event handler */
|
||||||
|
int run_global_service_event_handler(nagios_macros *mac, service *svc) {
|
||||||
|
char *raw_command = NULL;
|
||||||
|
char *processed_command = NULL;
|
||||||
|
char *raw_logentry = NULL;
|
||||||
|
char *processed_logentry = NULL;
|
||||||
|
char *command_output = NULL;
|
||||||
|
int early_timeout = FALSE;
|
||||||
|
double exectime = 0.0;
|
||||||
|
int result = 0;
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
struct timeval start_time;
|
||||||
|
struct timeval end_time;
|
||||||
|
int neb_result = OK;
|
||||||
|
#endif
|
||||||
|
int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;
|
||||||
|
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "run_global_service_event_handler()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* bail out if we shouldn't be running event handlers */
|
||||||
|
if(enable_event_handlers == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* a global service event handler command has not been defined */
|
||||||
|
if(global_service_event_handler == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 1, "Running global event handler for service '%s' on host '%s'...\n", svc->description, svc->host_name);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get start time */
|
||||||
|
gettimeofday(&start_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get the raw command line */
|
||||||
|
get_raw_command_line_r(mac, global_service_event_handler_ptr, global_service_event_handler, &raw_command, macro_options);
|
||||||
|
if(raw_command == NULL) {
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Raw global service event handler command line: %s\n", raw_command);
|
||||||
|
|
||||||
|
/* process any macros in the raw command line */
|
||||||
|
process_macros_r(mac, raw_command, &processed_command, macro_options);
|
||||||
|
my_free(raw_command);
|
||||||
|
if(processed_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Processed global service event handler command line: %s\n", processed_command);
|
||||||
|
|
||||||
|
if(log_event_handlers == TRUE) {
|
||||||
|
asprintf(&raw_logentry, "GLOBAL SERVICE EVENT HANDLER: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n", svc->host_name, svc->description, global_service_event_handler);
|
||||||
|
process_macros_r(mac, raw_logentry, &processed_logentry, macro_options);
|
||||||
|
logit(NSLOG_EVENT_HANDLER, FALSE, "%s", processed_logentry);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
end_time.tv_sec = 0L;
|
||||||
|
end_time.tv_usec = 0L;
|
||||||
|
neb_result = broker_event_handler(NEBTYPE_EVENTHANDLER_START, NEBFLAG_NONE, NEBATTR_NONE, GLOBAL_SERVICE_EVENTHANDLER, (void *)svc, svc->current_state, svc->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, global_service_event_handler, processed_command, NULL, NULL);
|
||||||
|
|
||||||
|
/* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
|
||||||
|
if(neb_result == NEBERROR_CALLBACKOVERRIDE) {
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* run the command */
|
||||||
|
result = my_system_r(mac, processed_command, event_handler_timeout, &early_timeout, &exectime, &command_output, 0);
|
||||||
|
|
||||||
|
/* check to see if the event handler timed out */
|
||||||
|
if(early_timeout == TRUE)
|
||||||
|
logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING, TRUE, "Warning: Global service event handler command '%s' timed out after %d seconds\n", processed_command, event_handler_timeout);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get end time */
|
||||||
|
gettimeofday(&end_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
broker_event_handler(NEBTYPE_EVENTHANDLER_END, NEBFLAG_NONE, NEBATTR_NONE, GLOBAL_SERVICE_EVENTHANDLER, (void *)svc, svc->current_state, svc->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, global_service_event_handler, processed_command, command_output, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(command_output);
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* runs a service event handler command */
|
||||||
|
int run_service_event_handler(nagios_macros *mac, service *svc) {
|
||||||
|
char *raw_command = NULL;
|
||||||
|
char *processed_command = NULL;
|
||||||
|
char *raw_logentry = NULL;
|
||||||
|
char *processed_logentry = NULL;
|
||||||
|
char *command_output = NULL;
|
||||||
|
int early_timeout = FALSE;
|
||||||
|
double exectime = 0.0;
|
||||||
|
int result = 0;
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
struct timeval start_time;
|
||||||
|
struct timeval end_time;
|
||||||
|
int neb_result = OK;
|
||||||
|
#endif
|
||||||
|
int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;
|
||||||
|
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "run_service_event_handler()\n");
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* bail if there's no command */
|
||||||
|
if(svc->event_handler == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 1, "Running event handler for service '%s' on host '%s'...\n", svc->description, svc->host_name);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get start time */
|
||||||
|
gettimeofday(&start_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* get the raw command line */
|
||||||
|
get_raw_command_line_r(mac, svc->event_handler_ptr, svc->event_handler, &raw_command, macro_options);
|
||||||
|
if(raw_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Raw service event handler command line: %s\n", raw_command);
|
||||||
|
|
||||||
|
/* process any macros in the raw command line */
|
||||||
|
process_macros_r(mac, raw_command, &processed_command, macro_options);
|
||||||
|
my_free(raw_command);
|
||||||
|
if(processed_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Processed service event handler command line: %s\n", processed_command);
|
||||||
|
|
||||||
|
if(log_event_handlers == TRUE) {
|
||||||
|
asprintf(&raw_logentry, "SERVICE EVENT HANDLER: %s;%s;$SERVICESTATE$;$SERVICESTATETYPE$;$SERVICEATTEMPT$;%s\n", svc->host_name, svc->description, svc->event_handler);
|
||||||
|
process_macros_r(mac, raw_logentry, &processed_logentry, macro_options);
|
||||||
|
logit(NSLOG_EVENT_HANDLER, FALSE, "%s", processed_logentry);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
end_time.tv_sec = 0L;
|
||||||
|
end_time.tv_usec = 0L;
|
||||||
|
neb_result = broker_event_handler(NEBTYPE_EVENTHANDLER_START, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_EVENTHANDLER, (void *)svc, svc->current_state, svc->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, svc->event_handler, processed_command, NULL, NULL);
|
||||||
|
|
||||||
|
/* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
|
||||||
|
if(neb_result == NEBERROR_CALLBACKOVERRIDE) {
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* run the command */
|
||||||
|
result = my_system_r(mac, processed_command, event_handler_timeout, &early_timeout, &exectime, &command_output, 0);
|
||||||
|
|
||||||
|
/* check to see if the event handler timed out */
|
||||||
|
if(early_timeout == TRUE)
|
||||||
|
logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING, TRUE, "Warning: Service event handler command '%s' timed out after %d seconds\n", processed_command, event_handler_timeout);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get end time */
|
||||||
|
gettimeofday(&end_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
broker_event_handler(NEBTYPE_EVENTHANDLER_END, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_EVENTHANDLER, (void *)svc, svc->current_state, svc->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, svc->event_handler, processed_command, command_output, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(command_output);
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/****************** HOST EVENT HANDLER FUNCTIONS ******************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* handles a change in the status of a host */
|
||||||
|
int handle_host_event(host *hst) {
|
||||||
|
nagios_macros mac;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "handle_host_event()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
broker_statechange_data(NEBTYPE_STATECHANGE_END, NEBFLAG_NONE, NEBATTR_NONE, HOST_STATECHANGE, (void *)hst, hst->current_state, hst->state_type, hst->current_attempt, hst->max_attempts, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* bail out if we shouldn't be running event handlers */
|
||||||
|
if(enable_event_handlers == FALSE)
|
||||||
|
return OK;
|
||||||
|
if(hst->event_handler_enabled == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* update host macros */
|
||||||
|
memset(&mac, 0, sizeof(mac));
|
||||||
|
grab_host_macros_r(&mac, hst);
|
||||||
|
|
||||||
|
/* run the global host event handler */
|
||||||
|
run_global_host_event_handler(&mac, hst);
|
||||||
|
|
||||||
|
/* run the event handler command if there is one */
|
||||||
|
if(hst->event_handler != NULL)
|
||||||
|
run_host_event_handler(&mac, hst);
|
||||||
|
|
||||||
|
/* check for external commands - the event handler may have given us some directives... */
|
||||||
|
check_for_external_commands();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* runs the global host event handler */
|
||||||
|
int run_global_host_event_handler(nagios_macros *mac, host *hst) {
|
||||||
|
char *raw_command = NULL;
|
||||||
|
char *processed_command = NULL;
|
||||||
|
char *raw_logentry = NULL;
|
||||||
|
char *processed_logentry = NULL;
|
||||||
|
char *command_output = NULL;
|
||||||
|
int early_timeout = FALSE;
|
||||||
|
double exectime = 0.0;
|
||||||
|
int result = 0;
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
struct timeval start_time;
|
||||||
|
struct timeval end_time;
|
||||||
|
int neb_result = OK;
|
||||||
|
#endif
|
||||||
|
int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;
|
||||||
|
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "run_global_host_event_handler()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* bail out if we shouldn't be running event handlers */
|
||||||
|
if(enable_event_handlers == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* no global host event handler command is defined */
|
||||||
|
if(global_host_event_handler == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 1, "Running global event handler for host '%s'..\n", hst->name);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get start time */
|
||||||
|
gettimeofday(&start_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get the raw command line */
|
||||||
|
get_raw_command_line_r(mac, global_host_event_handler_ptr, global_host_event_handler, &raw_command, macro_options);
|
||||||
|
if(raw_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Raw global host event handler command line: %s\n", raw_command);
|
||||||
|
|
||||||
|
/* process any macros in the raw command line */
|
||||||
|
process_macros_r(mac, raw_command, &processed_command, macro_options);
|
||||||
|
my_free(raw_command);
|
||||||
|
if(processed_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Processed global host event handler command line: %s\n", processed_command);
|
||||||
|
|
||||||
|
if(log_event_handlers == TRUE) {
|
||||||
|
asprintf(&raw_logentry, "GLOBAL HOST EVENT HANDLER: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n", hst->name, global_host_event_handler);
|
||||||
|
process_macros_r(mac, raw_logentry, &processed_logentry, macro_options);
|
||||||
|
logit(NSLOG_EVENT_HANDLER, FALSE, "%s", processed_logentry);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
end_time.tv_sec = 0L;
|
||||||
|
end_time.tv_usec = 0L;
|
||||||
|
neb_result = broker_event_handler(NEBTYPE_EVENTHANDLER_START, NEBFLAG_NONE, NEBATTR_NONE, GLOBAL_HOST_EVENTHANDLER, (void *)hst, hst->current_state, hst->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, global_host_event_handler, processed_command, NULL, NULL);
|
||||||
|
|
||||||
|
/* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
|
||||||
|
if(neb_result == NEBERROR_CALLBACKOVERRIDE) {
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* run the command */
|
||||||
|
result = my_system_r(mac, processed_command, event_handler_timeout, &early_timeout, &exectime, &command_output, 0);
|
||||||
|
|
||||||
|
/* check for a timeout in the execution of the event handler command */
|
||||||
|
if(early_timeout == TRUE)
|
||||||
|
logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING, TRUE, "Warning: Global host event handler command '%s' timed out after %d seconds\n", processed_command, event_handler_timeout);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get end time */
|
||||||
|
gettimeofday(&end_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
broker_event_handler(NEBTYPE_EVENTHANDLER_END, NEBFLAG_NONE, NEBATTR_NONE, GLOBAL_HOST_EVENTHANDLER, (void *)hst, hst->current_state, hst->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, global_host_event_handler, processed_command, command_output, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(command_output);
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* runs a host event handler command */
|
||||||
|
int run_host_event_handler(nagios_macros *mac, host *hst) {
|
||||||
|
char *raw_command = NULL;
|
||||||
|
char *processed_command = NULL;
|
||||||
|
char *raw_logentry = NULL;
|
||||||
|
char *processed_logentry = NULL;
|
||||||
|
char *command_output = NULL;
|
||||||
|
int early_timeout = FALSE;
|
||||||
|
double exectime = 0.0;
|
||||||
|
int result = 0;
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
struct timeval start_time;
|
||||||
|
struct timeval end_time;
|
||||||
|
int neb_result = OK;
|
||||||
|
#endif
|
||||||
|
int macro_options = STRIP_ILLEGAL_MACRO_CHARS | ESCAPE_MACRO_CHARS;
|
||||||
|
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_FUNCTIONS, 0, "run_host_event_handler()\n");
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* bail if there's no command */
|
||||||
|
if(hst->event_handler == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 1, "Running event handler for host '%s'..\n", hst->name);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get start time */
|
||||||
|
gettimeofday(&start_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get the raw command line */
|
||||||
|
get_raw_command_line_r(mac, hst->event_handler_ptr, hst->event_handler, &raw_command, macro_options);
|
||||||
|
if(raw_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Raw host event handler command line: %s\n", raw_command);
|
||||||
|
|
||||||
|
/* process any macros in the raw command line */
|
||||||
|
process_macros_r(mac, raw_command, &processed_command, macro_options);
|
||||||
|
my_free(raw_command);
|
||||||
|
if(processed_command == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
log_debug_info(DEBUGL_EVENTHANDLERS, 2, "Processed host event handler command line: %s\n", processed_command);
|
||||||
|
|
||||||
|
if(log_event_handlers == TRUE) {
|
||||||
|
asprintf(&raw_logentry, "HOST EVENT HANDLER: %s;$HOSTSTATE$;$HOSTSTATETYPE$;$HOSTATTEMPT$;%s\n", hst->name, hst->event_handler);
|
||||||
|
process_macros_r(mac, raw_logentry, &processed_logentry, macro_options);
|
||||||
|
logit(NSLOG_EVENT_HANDLER, FALSE, "%s", processed_logentry);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
end_time.tv_sec = 0L;
|
||||||
|
end_time.tv_usec = 0L;
|
||||||
|
neb_result = broker_event_handler(NEBTYPE_EVENTHANDLER_START, NEBFLAG_NONE, NEBATTR_NONE, HOST_EVENTHANDLER, (void *)hst, hst->current_state, hst->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, hst->event_handler, processed_command, NULL, NULL);
|
||||||
|
|
||||||
|
/* neb module wants to override (or cancel) the event handler - perhaps it will run the eventhandler itself */
|
||||||
|
if(neb_result == NEBERROR_CALLBACKOVERRIDE) {
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* run the command */
|
||||||
|
result = my_system_r(mac, processed_command, event_handler_timeout, &early_timeout, &exectime, &command_output, 0);
|
||||||
|
|
||||||
|
/* check to see if the event handler timed out */
|
||||||
|
if(early_timeout == TRUE)
|
||||||
|
logit(NSLOG_EVENT_HANDLER | NSLOG_RUNTIME_WARNING, TRUE, "Warning: Host event handler command '%s' timed out after %d seconds\n", processed_command, event_handler_timeout);
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* get end time */
|
||||||
|
gettimeofday(&end_time, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send event data to broker */
|
||||||
|
broker_event_handler(NEBTYPE_EVENTHANDLER_END, NEBFLAG_NONE, NEBATTR_NONE, HOST_EVENTHANDLER, (void *)hst, hst->current_state, hst->state_type, start_time, end_time, exectime, event_handler_timeout, early_timeout, result, hst->event_handler, processed_command, command_output, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(command_output);
|
||||||
|
my_free(processed_command);
|
||||||
|
my_free(raw_logentry);
|
||||||
|
my_free(processed_logentry);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
145
base/sretention.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* SRETENTION.C - State retention routines for Nagios
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2006 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 10-18-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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*********** COMMON HEADER FILES ***********/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
#include "../include/statusdata.h"
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
#include "../include/sretention.h"
|
||||||
|
#include "../include/broker.h"
|
||||||
|
|
||||||
|
extern int retain_state_information;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION SPECIFIC HEADER FILES ****/
|
||||||
|
#ifdef USE_XRDDEFAULT
|
||||||
|
#include "../xdata/xrddefault.h" /* default routines */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/************* TOP-LEVEL STATE INFORMATION FUNCTIONS **************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* initializes retention data at program start */
|
||||||
|
int initialize_retention_data(char *config_file) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XRDDEFAULT
|
||||||
|
result = xrddefault_initialize_retention_data(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* cleans up retention data before program termination */
|
||||||
|
int cleanup_retention_data(char *config_file) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XRDDEFAULT
|
||||||
|
result = xrddefault_cleanup_retention_data(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* save all host and service state information */
|
||||||
|
int save_state_information(int autosave) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
if(retain_state_information == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_retention_data(NEBTYPE_RETENTIONDATA_STARTSAVE, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/********* IMPLEMENTATION-SPECIFIC OUTPUT FUNCTION ********/
|
||||||
|
#ifdef USE_XRDDEFAULT
|
||||||
|
result = xrddefault_save_state_information();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_retention_data(NEBTYPE_RETENTIONDATA_ENDSAVE, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(result == ERROR)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
if(autosave == TRUE)
|
||||||
|
logit(NSLOG_PROCESS_INFO, FALSE, "Auto-save of retention data completed successfully.\n");
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* reads in initial host and state information */
|
||||||
|
int read_initial_state_information(void) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
if(retain_state_information == FALSE)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_retention_data(NEBTYPE_RETENTIONDATA_STARTLOAD, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/********* IMPLEMENTATION-SPECIFIC INPUT FUNCTION ********/
|
||||||
|
#ifdef USE_XRDDEFAULT
|
||||||
|
result = xrddefault_read_state_information();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_retention_data(NEBTYPE_RETENTIONDATA_ENDLOAD, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(result == ERROR)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
4526
base/utils.c
Normal file
3
cgi/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.o
|
||||||
|
*.cgi
|
||||||
|
Makefile
|
214
cgi/Makefile.in
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
###############################
|
||||||
|
# Makefile for Nagios CGIs
|
||||||
|
#
|
||||||
|
# Last Modified: 10-30-2008
|
||||||
|
###############################
|
||||||
|
|
||||||
|
|
||||||
|
# Source code directories
|
||||||
|
SRC_COMMON=../common
|
||||||
|
SRC_INCLUDE=../include
|
||||||
|
SRC_XDATA=../xdata
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
LOGDIR=@localstatedir@
|
||||||
|
CFGDIR=@sysconfdir@
|
||||||
|
BINDIR=@bindir@
|
||||||
|
CGIDIR=@sbindir@
|
||||||
|
HTMLDIR=@datarootdir@
|
||||||
|
INSTALL=@INSTALL@
|
||||||
|
INSTALL_OPTS=@INSTALL_OPTS@
|
||||||
|
COMMAND_OPTS=@COMMAND_OPTS@
|
||||||
|
STRIP=@STRIP@
|
||||||
|
|
||||||
|
CGIEXTRAS=@CGIEXTRAS@
|
||||||
|
|
||||||
|
CP=@CP@
|
||||||
|
CC=@CC@
|
||||||
|
CFLAGS=-Wall @CFLAGS@ @DEFS@ -DNSCGI
|
||||||
|
|
||||||
|
# Compiler flags for optimization (overrides default)
|
||||||
|
#CFLAGS=-O3 -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -DHAVE_CONFIG_H -DNSCGI
|
||||||
|
|
||||||
|
# Compiler flags for optimization (complements default)
|
||||||
|
#CFLAGS_WARN=-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs
|
||||||
|
#CFLAGS_DEBUG=-ggdb3 -g3
|
||||||
|
#CFLAGS+=$(CFLAGS_WARN) $(CFLAGS_DEBUG)
|
||||||
|
|
||||||
|
LDFLAGS=@LDFLAGS@
|
||||||
|
LIBS=@LIBS@
|
||||||
|
|
||||||
|
CGIS=avail.cgi cmd.cgi config.cgi extinfo.cgi history.cgi notifications.cgi outages.cgi showlog.cgi status.cgi statuswml.cgi summary.cgi tac.cgi $(CGIEXTRAS)
|
||||||
|
|
||||||
|
# External data I/O code and headers
|
||||||
|
XSDC=@XSDC@
|
||||||
|
XSDH=@XSDH@
|
||||||
|
XCDC=@XCDC@
|
||||||
|
XCDH=@XCDH@
|
||||||
|
XODC=@XODC@
|
||||||
|
XODH=@XODH@
|
||||||
|
XDDC=@XDDC@
|
||||||
|
XDDH=@XDDH@
|
||||||
|
|
||||||
|
# Generated automatically from configure script
|
||||||
|
SNPRINTF_O=@SNPRINTF_O@
|
||||||
|
|
||||||
|
# Object functions
|
||||||
|
ODATALIBS=objects-cgi.o xobjects-cgi.o
|
||||||
|
ODATAHDRS=
|
||||||
|
ODATADEPS=$(ODATALIBS)
|
||||||
|
|
||||||
|
# Host, service, and program status functions
|
||||||
|
SDATALIBS=statusdata-cgi.o xstatusdata-cgi.o comments-cgi.o downtime-cgi.o
|
||||||
|
SDATAHDRS=
|
||||||
|
SDATADEPS=$(SDATALIBS)
|
||||||
|
|
||||||
|
# Host and service comment functions
|
||||||
|
CDATALIBS=
|
||||||
|
CDATAHDRS=
|
||||||
|
CDATADEPS=$(CDATALIBS)
|
||||||
|
|
||||||
|
# Host and service downtime functions
|
||||||
|
DDATALIBS=
|
||||||
|
DDATAHDRS=
|
||||||
|
DDATADEPS=$(DDATALIBS)
|
||||||
|
|
||||||
|
# Common CGI functions (includes object and status functions)
|
||||||
|
CGILIBS=$(SRC_COMMON)/shared.o getcgi.o cgiutils.o cgiauth.o macros-cgi.o skiplist.o $(SNPRINTF_O) $(ODATALIBS) $(SDATALIBS)
|
||||||
|
CGIHDRS=$(SRC_INCLUDE)/config.h $(SRC_INCLUDE)/common.h $(SRC_INCLUDE)/locations.h
|
||||||
|
CGIDEPS=$(CGILIBS) $(ODATADEPS) $(SDATADEPS)
|
||||||
|
|
||||||
|
|
||||||
|
MATHLIBS=-lm
|
||||||
|
GDLIBS=@GDLIBS@
|
||||||
|
|
||||||
|
|
||||||
|
all cgis: $(CGIS)
|
||||||
|
|
||||||
|
$(CGILIBS): $(CGIHDRS)
|
||||||
|
|
||||||
|
|
||||||
|
######## REQUIRED LIBRARIES ##########
|
||||||
|
|
||||||
|
skiplist.o: $(SRC_COMMON)/skiplist.c $(SRC_INCLUDE)/skiplist.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/skiplist.c
|
||||||
|
|
||||||
|
macros-cgi.o: $(SRC_COMMON)/macros.c $(SRC_INCLUDE)/macros.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/macros.c
|
||||||
|
|
||||||
|
objects-cgi.o: $(SRC_COMMON)/objects.c $(SRC_INCLUDE)/objects.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/objects.c
|
||||||
|
|
||||||
|
xobjects-cgi.o: $(SRC_XDATA)/$(XODC) $(SRC_XDATA)/$(XODH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XODC)
|
||||||
|
|
||||||
|
statusdata-cgi.o: $(SRC_COMMON)/statusdata.c $(SRC_INCLUDE)/statusdata.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/statusdata.c
|
||||||
|
|
||||||
|
xstatusdata-cgi.o: $(SRC_XDATA)/$(XSDC) $(SRC_XDATA)/$(XSDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XSDC)
|
||||||
|
|
||||||
|
comments-cgi.o: $(SRC_COMMON)/comments.c $(SRC_INCLUDE)/comments.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/comments.c
|
||||||
|
|
||||||
|
xcomments-cgi.o: $(SRC_XDATA)/$(XCDC) $(SRC_XDATA)/$(XCDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XCDC)
|
||||||
|
|
||||||
|
downtime-cgi.o: $(SRC_COMMON)/downtime.c $(SRC_INCLUDE)/downtime.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_COMMON)/downtime.c
|
||||||
|
|
||||||
|
xdowntime-cgi.o: $(SRC_XDATA)/$(XDDC) $(SRC_XDATA)/$(XDDH)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $(SRC_XDATA)/$(XDDC)
|
||||||
|
|
||||||
|
$(SRC_COMMON)/shared.o: $(SRC_COMMON)/shared.c
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
########## CGIS ##########
|
||||||
|
|
||||||
|
avail.cgi: avail.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ avail.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
checksanity.cgi: checksanity.c $(CGIDEPS) $(CDATADEPS) $(DDATADEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ checksanity.c $(CGILIBS) $(CDATALIBS) $(DDATALIBS) $(LIBS)
|
||||||
|
|
||||||
|
cmd.cgi: cmd.c $(CGIDEPS) $(CDATADEPS) $(DDATADEPS) extcmd_list.o
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ cmd.c extcmd_list.o $(CGILIBS) $(CDATALIBS) $(DDATALIBS) $(LIBS)
|
||||||
|
|
||||||
|
config.cgi: config.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ config.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
extinfo.cgi: extinfo.c $(CGIDEPS) $(CDATADEPS) $(DDATADEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ extinfo.c $(CGILIBS) $(CDATALIBS) $(DDATALIBS) $(LIBS)
|
||||||
|
|
||||||
|
history.cgi: history.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ history.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
ministatus.cgi: ministatus.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ ministatus.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
notifications.cgi: notifications.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ notifications.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
outages.cgi: outages.c $(CGIDEPS) $(CDATADEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ outages.c $(CGILIBS) $(CDATALIBS) $(LIBS)
|
||||||
|
|
||||||
|
showlog.cgi: showlog.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ showlog.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
status.cgi: status.c $(CGIDEPS) $(CDATADEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ status.c $(CGILIBS) $(CDATALIBS) $(LIBS)
|
||||||
|
|
||||||
|
statuswml.cgi: statuswml.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ statuswml.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
statusmap.cgi: statusmap.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ statusmap.c $(CGILIBS) $(GDLIBS) $(LIBS)
|
||||||
|
|
||||||
|
statuswrl.cgi: statuswrl.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ statuswrl.c $(CGILIBS) $(MATHLIBS) $(LIBS)
|
||||||
|
|
||||||
|
summary.cgi: summary.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ summary.c $(CGILIBS) $(LIBS)
|
||||||
|
|
||||||
|
tac.cgi: tac.c $(CGIDEPS) $(CDATADEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ tac.c $(CGILIBS) $(CDATALIBS) $(LIBS)
|
||||||
|
|
||||||
|
tac-xml.cgi: tac-xml.c $(CGIDEPS) $(CDATADEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ tac-xml.c $(CGILIBS) $(CDATALIBS) $(LIBS)
|
||||||
|
|
||||||
|
trends.cgi: trends.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ trends.c $(CGILIBS) $(GDLIBS) $(LIBS)
|
||||||
|
|
||||||
|
histogram.cgi: histogram.c $(CGIDEPS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ histogram.c $(CGILIBS) $(GDLIBS) $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(CGIS)
|
||||||
|
rm -f *.o core gmon.out
|
||||||
|
rm -f *~ *.*~
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile cgiutils.h
|
||||||
|
|
||||||
|
devclean: distclean
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(MAKE) install-basic
|
||||||
|
$(MAKE) strip-post-install
|
||||||
|
|
||||||
|
install-unstripped:
|
||||||
|
$(MAKE) install-basic
|
||||||
|
|
||||||
|
install-basic:
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CGIDIR)
|
||||||
|
for file in *.cgi; do \
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) $$file $(DESTDIR)$(CGIDIR); \
|
||||||
|
done
|
||||||
|
|
||||||
|
strip-post-install:
|
||||||
|
for file in *.cgi; do \
|
||||||
|
$(STRIP) $(DESTDIR)$(CGIDIR)/$$file; \
|
||||||
|
done
|
||||||
|
|
||||||
|
|
4871
cgi/avail.c
Normal file
610
cgi/cgiauth.c
Normal file
@ -0,0 +1,610 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* CGIAUTH.C - Authorization utilities for Nagios CGIs
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 11-30-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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
|
||||||
|
#include "../include/cgiutils.h"
|
||||||
|
#include "../include/cgiauth.h"
|
||||||
|
|
||||||
|
extern char main_config_file[MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
extern hostgroup *hostgroup_list;
|
||||||
|
extern servicegroup *servicegroup_list;
|
||||||
|
|
||||||
|
extern int use_authentication;
|
||||||
|
extern int use_ssl_authentication;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* get current authentication information */
|
||||||
|
int get_authentication_information(authdata *authinfo) {
|
||||||
|
mmapfile *thefile;
|
||||||
|
char *input = NULL;
|
||||||
|
char *temp_ptr = NULL;
|
||||||
|
contact *temp_contact = NULL;
|
||||||
|
contactgroup *temp_contactgroup = NULL;
|
||||||
|
|
||||||
|
if(authinfo == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* initial values... */
|
||||||
|
authinfo->authorized_for_all_hosts = FALSE;
|
||||||
|
authinfo->authorized_for_all_host_commands = FALSE;
|
||||||
|
authinfo->authorized_for_all_services = FALSE;
|
||||||
|
authinfo->authorized_for_all_service_commands = FALSE;
|
||||||
|
authinfo->authorized_for_system_information = FALSE;
|
||||||
|
authinfo->authorized_for_system_commands = FALSE;
|
||||||
|
authinfo->authorized_for_configuration_information = FALSE;
|
||||||
|
authinfo->authorized_for_read_only = FALSE;
|
||||||
|
|
||||||
|
/* grab username from the environment... */
|
||||||
|
if(use_ssl_authentication) {
|
||||||
|
/* patch by Pawl Zuzelski - 7/22/08 */
|
||||||
|
temp_ptr = getenv("SSL_CLIENT_S_DN_CN");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temp_ptr = getenv("REMOTE_USER");
|
||||||
|
}
|
||||||
|
if(temp_ptr == NULL) {
|
||||||
|
authinfo->username = "";
|
||||||
|
authinfo->authenticated = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
authinfo->username = (char *)malloc(strlen(temp_ptr) + 1);
|
||||||
|
if(authinfo->username == NULL)
|
||||||
|
authinfo->username = "";
|
||||||
|
else
|
||||||
|
strcpy(authinfo->username, temp_ptr);
|
||||||
|
if(!strcmp(authinfo->username, ""))
|
||||||
|
authinfo->authenticated = FALSE;
|
||||||
|
else
|
||||||
|
authinfo->authenticated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read in authorization override vars from config file... */
|
||||||
|
if((thefile = mmap_fopen(get_cgi_config_location())) != NULL) {
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
free(input);
|
||||||
|
|
||||||
|
/* read the next line */
|
||||||
|
if((input = mmap_fgets_multiline(thefile)) == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
strip(input);
|
||||||
|
|
||||||
|
/* we don't have a username yet, so fake the authentication if we find a default username defined */
|
||||||
|
if(!strcmp(authinfo->username, "") && strstr(input, "default_user_name=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
temp_ptr = strtok(NULL, ",");
|
||||||
|
authinfo->username = (char *)malloc(strlen(temp_ptr) + 1);
|
||||||
|
if(authinfo->username == NULL)
|
||||||
|
authinfo->username = "";
|
||||||
|
else
|
||||||
|
strcpy(authinfo->username, temp_ptr);
|
||||||
|
if(!strcmp(authinfo->username, ""))
|
||||||
|
authinfo->authenticated = FALSE;
|
||||||
|
else
|
||||||
|
authinfo->authenticated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(strstr(input, "authorized_for_all_hosts=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_all_hosts = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_for_all_services=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_all_services = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_for_system_information=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_system_information = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_for_configuration_information=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_configuration_information = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_for_all_host_commands=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_all_host_commands = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_for_all_service_commands=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_all_service_commands = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_for_system_commands=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_system_commands = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_for_read_only=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
if(!strcmp(temp_ptr, authinfo->username) || !strcmp(temp_ptr, "*"))
|
||||||
|
authinfo->authorized_for_read_only = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if((temp_contact = find_contact(authinfo->username)) != NULL) {
|
||||||
|
if(strstr(input, "authorized_contactgroup_for_all_hosts=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_all_hosts = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_contactgroup_for_all_services=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_all_services = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_contactgroup_for_system_information=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_system_information = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_contactgroup_for_configuration_information=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_configuration_information = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_contactgroup_for_all_host_commands=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_all_host_commands = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_contactgroup_for_all_service_commands=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_all_service_commands = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_contactgroup_for_system_commands=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_system_commands = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strstr(input, "authorized_contactgroup_for_read_only=") == input) {
|
||||||
|
temp_ptr = strtok(input, "=");
|
||||||
|
while((temp_ptr = strtok(NULL, ","))) {
|
||||||
|
temp_contactgroup = find_contactgroup(temp_ptr);
|
||||||
|
if(is_contact_member_of_contactgroup(temp_contactgroup, temp_contact))
|
||||||
|
authinfo->authorized_for_read_only = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory and close the file */
|
||||||
|
free(input);
|
||||||
|
mmap_fclose(thefile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(authinfo->authenticated == TRUE)
|
||||||
|
return OK;
|
||||||
|
else
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* check if user is authorized to view information about a particular host */
|
||||||
|
int is_authorized_for_host(host *hst, authdata *authinfo) {
|
||||||
|
contact *temp_contact;
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if this user is authorized for all hosts, they are for this one... */
|
||||||
|
if(is_authorized_for_all_hosts(authinfo) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* find the contact */
|
||||||
|
temp_contact = find_contact(authinfo->username);
|
||||||
|
|
||||||
|
/* see if this user is a contact for the host */
|
||||||
|
if(is_contact_for_host(hst, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* see if this user is an escalated contact for the host */
|
||||||
|
if(is_escalated_contact_for_host(hst, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check if user is authorized to view information about all hosts in a particular hostgroup */
|
||||||
|
int is_authorized_for_hostgroup(hostgroup *hg, authdata *authinfo) {
|
||||||
|
hostsmember *temp_hostsmember;
|
||||||
|
host *temp_host;
|
||||||
|
|
||||||
|
if(hg == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* CHANGED in 2.0 - user must be authorized for ALL hosts in a hostgroup, not just one */
|
||||||
|
/* see if user is authorized for all hosts in the hostgroup */
|
||||||
|
/*
|
||||||
|
for(temp_hostsmember = hg->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
|
||||||
|
temp_host = find_host(temp_hostsmember->host_name);
|
||||||
|
if(is_authorized_for_host(temp_host, authinfo) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/* Reverted for 3.3.2 - must only be a member of one hostgroup */
|
||||||
|
for(temp_hostsmember = hg->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
|
||||||
|
temp_host = find_host(temp_hostsmember->host_name);
|
||||||
|
if(is_authorized_for_host(temp_host, authinfo) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*return TRUE;*/
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* check if user is authorized to view information about all services in a particular servicegroup */
|
||||||
|
int is_authorized_for_servicegroup(servicegroup *sg, authdata *authinfo) {
|
||||||
|
servicesmember *temp_servicesmember;
|
||||||
|
service *temp_service;
|
||||||
|
|
||||||
|
if(sg == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* see if user is authorized for all services in the servicegroup */
|
||||||
|
/*
|
||||||
|
for(temp_servicesmember = sg->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) {
|
||||||
|
temp_service = find_service(temp_servicesmember->host_name, temp_servicesmember->service_description);
|
||||||
|
if(is_authorized_for_service(temp_service, authinfo) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/* Reverted for 3.3.2 - must only be a member of one hostgroup */
|
||||||
|
for(temp_servicesmember = sg->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) {
|
||||||
|
temp_service = find_service(temp_servicesmember->host_name, temp_servicesmember->service_description);
|
||||||
|
if(is_authorized_for_service(temp_service, authinfo) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*return TRUE*/;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if current user is restricted to read only */
|
||||||
|
int is_authorized_for_read_only(authdata *authinfo) {
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return authinfo->authorized_for_read_only;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if user is authorized to view information about a particular service */
|
||||||
|
int is_authorized_for_service(service *svc, authdata *authinfo) {
|
||||||
|
host *temp_host;
|
||||||
|
contact *temp_contact;
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if this user is authorized for all services, they are for this one... */
|
||||||
|
if(is_authorized_for_all_services(authinfo) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* find the host */
|
||||||
|
temp_host = find_host(svc->host_name);
|
||||||
|
if(temp_host == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if this user is authorized for this host, they are for all services on it as well... */
|
||||||
|
if(is_authorized_for_host(temp_host, authinfo) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* find the contact */
|
||||||
|
temp_contact = find_contact(authinfo->username);
|
||||||
|
|
||||||
|
/* see if this user is a contact for the service */
|
||||||
|
if(is_contact_for_service(svc, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* see if this user is an escalated contact for the service */
|
||||||
|
if(is_escalated_contact_for_service(svc, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check if current user is authorized to view information on all hosts */
|
||||||
|
int is_authorized_for_all_hosts(authdata *authinfo) {
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return authinfo->authorized_for_all_hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check if current user is authorized to view information on all service */
|
||||||
|
int is_authorized_for_all_services(authdata *authinfo) {
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return authinfo->authorized_for_all_services;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check if current user is authorized to view system information */
|
||||||
|
int is_authorized_for_system_information(authdata *authinfo) {
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return authinfo->authorized_for_system_information;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check if current user is authorized to view configuration information */
|
||||||
|
int is_authorized_for_configuration_information(authdata *authinfo) {
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return authinfo->authorized_for_configuration_information;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check if current user is authorized to issue system commands */
|
||||||
|
int is_authorized_for_system_commands(authdata *authinfo) {
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return authinfo->authorized_for_system_commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check is the current user is authorized to issue commands relating to a particular service */
|
||||||
|
int is_authorized_for_service_commands(service *svc, authdata *authinfo) {
|
||||||
|
host *temp_host;
|
||||||
|
contact *temp_contact;
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* the user is authorized if they have rights to the service */
|
||||||
|
if(is_authorized_for_service(svc, authinfo) == TRUE) {
|
||||||
|
|
||||||
|
/* find the host */
|
||||||
|
temp_host = find_host(svc->host_name);
|
||||||
|
if(temp_host == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* find the contact */
|
||||||
|
temp_contact = find_contact(authinfo->username);
|
||||||
|
|
||||||
|
/* reject if contact is not allowed to issue commands */
|
||||||
|
if(temp_contact && temp_contact->can_submit_commands == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* see if this user is a contact for the host */
|
||||||
|
if(is_contact_for_host(temp_host, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* see if this user is an escalated contact for the host */
|
||||||
|
if(is_escalated_contact_for_host(temp_host, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* this user is a contact for the service, so they have permission... */
|
||||||
|
if(is_contact_for_service(svc, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* this user is an escalated contact for the service, so they have permission... */
|
||||||
|
if(is_escalated_contact_for_service(svc, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* this user is not a contact for the host, so they must have been given explicit permissions to all service commands */
|
||||||
|
if(authinfo->authorized_for_all_service_commands == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check is the current user is authorized to issue commands relating to a particular host */
|
||||||
|
int is_authorized_for_host_commands(host *hst, authdata *authinfo) {
|
||||||
|
contact *temp_contact;
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* if we're not using authentication, fake it */
|
||||||
|
if(use_authentication == FALSE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* if this user has not authenticated return error */
|
||||||
|
if(authinfo->authenticated == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* the user is authorized if they have rights to the host */
|
||||||
|
if(is_authorized_for_host(hst, authinfo) == TRUE) {
|
||||||
|
|
||||||
|
/* find the contact */
|
||||||
|
temp_contact = find_contact(authinfo->username);
|
||||||
|
|
||||||
|
/* reject if contact is not allowed to issue commands */
|
||||||
|
if(temp_contact && temp_contact->can_submit_commands == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* this user is a contact for the host, so they have permission... */
|
||||||
|
if(is_contact_for_host(hst, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* this user is an escalated contact for the host, so they have permission... */
|
||||||
|
if(is_escalated_contact_for_host(hst, temp_contact) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* this user is not a contact for the host, so they must have been given explicit permissions to all host commands */
|
||||||
|
if(authinfo->authorized_for_all_host_commands == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check is the current user is authorized to issue commands relating to a particular servicegroup */
|
||||||
|
int is_authorized_for_servicegroup_commands(servicegroup *sg, authdata *authinfo) {
|
||||||
|
servicesmember *temp_servicesmember;
|
||||||
|
service *temp_service;
|
||||||
|
|
||||||
|
if(sg == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* see if user is authorized for all services commands in the servicegroup */
|
||||||
|
for(temp_servicesmember = sg->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) {
|
||||||
|
temp_service = find_service(temp_servicesmember->host_name, temp_servicesmember->service_description);
|
||||||
|
if(is_authorized_for_service_commands(temp_service, authinfo) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* check is the current user is authorized to issue commands relating to a particular hostgroup */
|
||||||
|
int is_authorized_for_hostgroup_commands(hostgroup *hg, authdata *authinfo) {
|
||||||
|
hostsmember *temp_hostsmember;
|
||||||
|
host *temp_host;
|
||||||
|
|
||||||
|
if(hg == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* see if user is authorized for all hosts in the hostgroup */
|
||||||
|
for(temp_hostsmember = hg->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
|
||||||
|
temp_host = find_host(temp_hostsmember->host_name);
|
||||||
|
if(is_authorized_for_host_commands(temp_host, authinfo) == FALSE)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
1874
cgi/cgiutils.c
Normal file
2483
cgi/config.c
Normal file
223
cgi/extcmd_list.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../include/common.h"
|
||||||
|
|
||||||
|
struct nagios_extcmd {
|
||||||
|
const char *name;
|
||||||
|
int id;
|
||||||
|
/* size_t namelen;
|
||||||
|
int min_args;
|
||||||
|
int (*handler)(struct nagios_extcmd *, int, char **);
|
||||||
|
struct nagios_extcmd *next_handler;
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CMD_DEF(name, min_args, handler) \
|
||||||
|
{ #name, CMD_ ## name }
|
||||||
|
/* { #name, sizeof(#name) - 1, CMD_ ## name, min_args, handler, NULL } */
|
||||||
|
struct nagios_extcmd in_core_commands[] = {
|
||||||
|
CMD_DEF(NONE, 0, NULL),
|
||||||
|
CMD_DEF(ADD_HOST_COMMENT, 0, NULL),
|
||||||
|
CMD_DEF(DEL_HOST_COMMENT, 0, NULL),
|
||||||
|
CMD_DEF(ADD_SVC_COMMENT, 0, NULL),
|
||||||
|
CMD_DEF(DEL_SVC_COMMENT, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SVC_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SVC_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_SVC_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(DELAY_SVC_NOTIFICATION, 0, NULL),
|
||||||
|
CMD_DEF(DELAY_HOST_NOTIFICATION, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(RESTART_PROCESS, 0, NULL),
|
||||||
|
CMD_DEF(SHUTDOWN_PROCESS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_HOST_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DELAY_HOST_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DEL_ALL_HOST_COMMENTS, 0, NULL),
|
||||||
|
CMD_DEF(DEL_ALL_SVC_COMMENTS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(PROCESS_SERVICE_CHECK_RESULT, 0, NULL),
|
||||||
|
CMD_DEF(SAVE_STATE_INFORMATION, 0, NULL),
|
||||||
|
CMD_DEF(READ_STATE_INFORMATION, 0, NULL),
|
||||||
|
CMD_DEF(ACKNOWLEDGE_HOST_PROBLEM, 0, NULL),
|
||||||
|
CMD_DEF(ACKNOWLEDGE_SVC_PROBLEM, 0, NULL),
|
||||||
|
CMD_DEF(START_EXECUTING_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(STOP_EXECUTING_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(START_ACCEPTING_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(STOP_ACCEPTING_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_EVENT_HANDLERS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_EVENT_HANDLERS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SVC_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SVC_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(START_OBSESSING_OVER_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(STOP_OBSESSING_OVER_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(REMOVE_HOST_ACKNOWLEDGEMENT, 0, NULL),
|
||||||
|
CMD_DEF(REMOVE_SVC_ACKNOWLEDGEMENT, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_FORCED_HOST_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_FORCED_SVC_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_FLAP_DETECTION, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_FLAP_DETECTION, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SVC_FLAP_DETECTION, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SVC_FLAP_DETECTION, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_FLAP_DETECTION, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_FLAP_DETECTION, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOSTGROUP_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOSTGROUP_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOSTGROUP_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOSTGROUP_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOSTGROUP_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOSTGROUP_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_ACTIVE_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_PENDING_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_ACTIVE_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_PENDING_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_ACTIVE_HOST_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CANCEL_PENDING_HOST_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(FLUSH_PENDING_COMMANDS, 0, NULL),
|
||||||
|
CMD_DEF(DEL_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(DEL_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_FAILURE_PREDICTION, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_FAILURE_PREDICTION, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_PERFORMANCE_DATA, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_PERFORMANCE_DATA, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_HOSTGROUP_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_HOSTGROUP_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_HOST_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(PROCESS_HOST_CHECK_RESULT, 0, NULL),
|
||||||
|
CMD_DEF(START_EXECUTING_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(STOP_EXECUTING_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(START_ACCEPTING_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(STOP_ACCEPTING_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(START_OBSESSING_OVER_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(STOP_OBSESSING_OVER_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_HOST_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_FORCED_HOST_CHECK, 0, NULL),
|
||||||
|
CMD_DEF(START_OBSESSING_OVER_SVC, 0, NULL),
|
||||||
|
CMD_DEF(STOP_OBSESSING_OVER_SVC, 0, NULL),
|
||||||
|
CMD_DEF(START_OBSESSING_OVER_HOST, 0, NULL),
|
||||||
|
CMD_DEF(STOP_OBSESSING_OVER_HOST, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOSTGROUP_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOSTGROUP_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SERVICEGROUP_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SERVICEGROUP_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SERVICEGROUP_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SERVICEGROUP_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_SERVICEGROUP_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_SERVICEGROUP_SVC_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_GLOBAL_HOST_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_GLOBAL_SVC_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_HOST_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_SVC_EVENT_HANDLER, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_HOST_CHECK_COMMAND, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_SVC_CHECK_COMMAND, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_NORMAL_HOST_CHECK_INTERVAL, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_NORMAL_SVC_CHECK_INTERVAL, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_RETRY_SVC_CHECK_INTERVAL, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_MAX_HOST_CHECK_ATTEMPTS, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_MAX_SVC_CHECK_ATTEMPTS, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_AND_CHILD_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_AND_CHILD_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_SERVICE_FRESHNESS_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_SERVICE_FRESHNESS_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_HOST_FRESHNESS_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_HOST_FRESHNESS_CHECKS, 0, NULL),
|
||||||
|
CMD_DEF(SET_HOST_NOTIFICATION_NUMBER, 0, NULL),
|
||||||
|
CMD_DEF(SET_SVC_NOTIFICATION_NUMBER, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_HOST_CHECK_TIMEPERIOD, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_SVC_CHECK_TIMEPERIOD, 0, NULL),
|
||||||
|
CMD_DEF(PROCESS_FILE, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CUSTOM_HOST_VAR, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CUSTOM_SVC_VAR, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CUSTOM_CONTACT_VAR, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_CONTACT_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_CONTACT_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_CONTACT_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_CONTACT_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_RETRY_HOST_CHECK_INTERVAL, 0, NULL),
|
||||||
|
CMD_DEF(SEND_CUSTOM_HOST_NOTIFICATION, 0, NULL),
|
||||||
|
CMD_DEF(SEND_CUSTOM_SVC_NOTIFICATION, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_HOST_NOTIFICATION_TIMEPERIOD, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_SVC_NOTIFICATION_TIMEPERIOD, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_HOST_MODATTR, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_SVC_MODATTR, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CONTACT_MODATTR, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CONTACT_MODHATTR, 0, NULL),
|
||||||
|
CMD_DEF(CHANGE_CONTACT_MODSATTR, 0, NULL),
|
||||||
|
};
|
||||||
|
#undef CMD_DEF
|
||||||
|
|
||||||
|
#ifndef ARRAY_SIZE
|
||||||
|
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *extcmd_get_name(int id) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < ARRAY_SIZE(in_core_commands); i++) {
|
||||||
|
struct nagios_extcmd *ecmd;
|
||||||
|
ecmd = &in_core_commands[i];
|
||||||
|
if(ecmd->id == id)
|
||||||
|
return ecmd->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ECMD_LIST_TESTING
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
int i, no_handler = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < ARRAY_SIZE(in_core_commands); i++) {
|
||||||
|
struct nagios_extcmd *cmd = &in_core_commands[i];
|
||||||
|
if(!cmd->handler) {
|
||||||
|
no_handler++;
|
||||||
|
printf("%s has no handler\n", extcmd_get_name(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("%d of %d commands have no handler\n",
|
||||||
|
no_handler, ARRAY_SIZE(in_core_commands));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
3200
cgi/extinfo.c
Normal file
517
cgi/getcgi.c
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
/******************************************
|
||||||
|
*
|
||||||
|
* GETCGI.C - Nagios CGI Input Routines
|
||||||
|
*
|
||||||
|
* Last Modified: 05-15-2006
|
||||||
|
*
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/getcgi.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
#undef PARANOID_CGI_INPUT
|
||||||
|
|
||||||
|
|
||||||
|
/* Remove potentially harmful characters from CGI input that we don't need or want */
|
||||||
|
void sanitize_cgi_input(char **cgivars) {
|
||||||
|
char *strptr;
|
||||||
|
int x, y, i;
|
||||||
|
int keep;
|
||||||
|
|
||||||
|
/* don't strip for now... */
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(strptr = cgivars[i = 0]; strptr != NULL; strptr = cgivars[++i]) {
|
||||||
|
|
||||||
|
for(x = 0, y = 0; strptr[x] != '\x0'; x++) {
|
||||||
|
|
||||||
|
keep = 1;
|
||||||
|
|
||||||
|
/* remove potentially nasty characters */
|
||||||
|
if(strptr[x] == ';' || strptr[x] == '|' || strptr[x] == '&' || strptr[x] == '<' || strptr[x] == '>')
|
||||||
|
keep = 0;
|
||||||
|
#ifdef PARANOID_CGI_INPUT
|
||||||
|
else if(strptr[x] == '/' || strptr[x] == '\\')
|
||||||
|
keep = 0;
|
||||||
|
#endif
|
||||||
|
if(keep == 1)
|
||||||
|
strptr[y++] = strptr[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
strptr[y] = '\x0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* convert encoded hex string (2 characters representing an 8-bit number) to its ASCII char equivalent */
|
||||||
|
unsigned char hex_to_char(char *input) {
|
||||||
|
unsigned char outchar = '\x0';
|
||||||
|
unsigned int outint;
|
||||||
|
char tempbuf[3];
|
||||||
|
|
||||||
|
/* NULL or empty string */
|
||||||
|
if(input == NULL)
|
||||||
|
return '\x0';
|
||||||
|
if(input[0] == '\x0')
|
||||||
|
return '\x0';
|
||||||
|
|
||||||
|
tempbuf[0] = input[0];
|
||||||
|
tempbuf[1] = input[1];
|
||||||
|
tempbuf[2] = '\x0';
|
||||||
|
|
||||||
|
sscanf(tempbuf, "%X", &outint);
|
||||||
|
|
||||||
|
/* only convert "normal" ASCII characters - we don't want the rest. Normally you would
|
||||||
|
convert all characters (i.e. for allowing users to post binary files), but since we
|
||||||
|
aren't doing this, stay on the cautious side of things and reject outsiders... */
|
||||||
|
#ifdef PARANOID_CGI_INPUT
|
||||||
|
if(outint < 32 || outint > 126)
|
||||||
|
outint = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
outchar = (unsigned char)outint;
|
||||||
|
|
||||||
|
return outchar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* unescape hex characters in CGI input */
|
||||||
|
void unescape_cgi_input(char *input) {
|
||||||
|
int x, y;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(input == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
len = strlen(input);
|
||||||
|
for(x = 0, y = 0; x < len; x++, y++) {
|
||||||
|
|
||||||
|
if(input[x] == '\x0')
|
||||||
|
break;
|
||||||
|
else if(input[x] == '%') {
|
||||||
|
input[y] = hex_to_char(&input[x + 1]);
|
||||||
|
x += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input[y] = input[x];
|
||||||
|
}
|
||||||
|
input[y] = '\x0';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* read the CGI input and place all name/val pairs into list. returns list containing name1, value1, name2, value2, ... , NULL */
|
||||||
|
/* this is a hacked version of a routine I found a long time ago somewhere - can't remember where anymore */
|
||||||
|
char **getcgivars(void) {
|
||||||
|
register int i;
|
||||||
|
char *accept_language;
|
||||||
|
char *request_method;
|
||||||
|
char *content_type;
|
||||||
|
char *content_length_string;
|
||||||
|
int content_length;
|
||||||
|
char *cgiinput;
|
||||||
|
char **cgivars;
|
||||||
|
char **pairlist;
|
||||||
|
int paircount;
|
||||||
|
char *nvpair;
|
||||||
|
char *eqpos;
|
||||||
|
|
||||||
|
/* initialize char variable(s) */
|
||||||
|
cgiinput = "";
|
||||||
|
|
||||||
|
/* Attempt to set the locale */
|
||||||
|
accept_language = getenv("HTTP_ACCEPT_LANGUAGE");
|
||||||
|
process_language(accept_language);
|
||||||
|
|
||||||
|
/* depending on the request method, read all CGI input into cgiinput */
|
||||||
|
|
||||||
|
request_method = getenv("REQUEST_METHOD");
|
||||||
|
if(request_method == NULL)
|
||||||
|
request_method = "";
|
||||||
|
|
||||||
|
if(!strcmp(request_method, "GET") || !strcmp(request_method, "HEAD")) {
|
||||||
|
|
||||||
|
/* check for NULL query string environment variable - 04/28/00 (Ludo Bosmans) */
|
||||||
|
if(getenv("QUERY_STRING") == NULL) {
|
||||||
|
cgiinput = (char *)malloc(1);
|
||||||
|
if(cgiinput != NULL)
|
||||||
|
cgiinput[0] = '\x0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cgiinput = strdup(getenv("QUERY_STRING"));
|
||||||
|
if(cgiinput == NULL) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for CGI input.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(!strcmp(request_method, "POST") || !strcmp(request_method, "PUT")) {
|
||||||
|
|
||||||
|
/* if CONTENT_TYPE variable is not specified, RFC-2068 says we should assume it is "application/octet-string" */
|
||||||
|
/* mobile (WAP) stations generate CONTENT_TYPE with charset, we we should only check first 33 chars */
|
||||||
|
|
||||||
|
content_type = getenv("CONTENT_TYPE");
|
||||||
|
if(content_type == NULL)
|
||||||
|
content_type = "";
|
||||||
|
|
||||||
|
if(strlen(content_type) && strncasecmp(content_type, "application/x-www-form-urlencoded", 33)) {
|
||||||
|
printf("getcgivars(): Unsupported Content-Type.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
content_length_string = getenv("CONTENT_LENGTH");
|
||||||
|
if(content_length_string == NULL)
|
||||||
|
content_length_string = "0";
|
||||||
|
|
||||||
|
if(!(content_length = atoi(content_length_string))) {
|
||||||
|
printf("getcgivars(): No Content-Length was sent with the POST request.\n") ;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* suspicious content length */
|
||||||
|
if((content_length < 0) || (content_length >= INT_MAX - 1)) {
|
||||||
|
printf("getcgivars(): Suspicious Content-Length was sent with the POST request.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(cgiinput = (char *)malloc(content_length + 1))) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for CGI input.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if(!fread(cgiinput, content_length, 1, stdin)) {
|
||||||
|
printf("getcgivars(): Could not read input from STDIN.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
cgiinput[content_length] = '\0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
printf("getcgivars(): Unsupported REQUEST_METHOD -> '%s'\n", request_method);
|
||||||
|
printf("\n");
|
||||||
|
printf("I'm guessing you're trying to execute the CGI from a command line.\n");
|
||||||
|
printf("In order to do that, you need to set the REQUEST_METHOD environment\n");
|
||||||
|
printf("variable to either \"GET\", \"HEAD\", or \"POST\". When using the\n");
|
||||||
|
printf("GET and HEAD methods, arguments can be passed to the CGI\n");
|
||||||
|
printf("by setting the \"QUERY_STRING\" environment variable. If you're\n");
|
||||||
|
printf("using the POST method, data is read from standard input. Also of\n");
|
||||||
|
printf("note: if you've enabled authentication in the CGIs, you must set the\n");
|
||||||
|
printf("\"REMOTE_USER\" environment variable to be the name of the user you're\n");
|
||||||
|
printf("\"authenticated\" as.\n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* change all plus signs back to spaces */
|
||||||
|
for(i = 0; cgiinput[i]; i++) {
|
||||||
|
if(cgiinput[i] == '+')
|
||||||
|
cgiinput[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first, split on ampersands (&) to extract the name-value pairs into pairlist */
|
||||||
|
/* allocate memory for 256 name-value pairs at a time, increasing by same
|
||||||
|
amount as necessary... */
|
||||||
|
pairlist = (char **)malloc(256 * sizeof(char **));
|
||||||
|
if(pairlist == NULL) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for name-value pairlist.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
paircount = 0;
|
||||||
|
nvpair = strtok(cgiinput, "&");
|
||||||
|
while(nvpair) {
|
||||||
|
pairlist[paircount] = strdup(nvpair);
|
||||||
|
if(NULL == pairlist[paircount]) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for name-value pair #%d.\n", paircount);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
paircount++;
|
||||||
|
if(!(paircount % 256)) {
|
||||||
|
pairlist = (char **)realloc(pairlist, (paircount + 256) * sizeof(char **));
|
||||||
|
if(pairlist == NULL) {
|
||||||
|
printf("getcgivars(): Could not re-allocate memory for name-value pairlist.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nvpair = strtok(NULL, "&");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* terminate the list */
|
||||||
|
pairlist[paircount] = '\x0';
|
||||||
|
|
||||||
|
/* extract the names and values from the pairlist */
|
||||||
|
cgivars = (char **)malloc((paircount * 2 + 1) * sizeof(char **));
|
||||||
|
if(cgivars == NULL) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for name-value list.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
for(i = 0; i < paircount; i++) {
|
||||||
|
|
||||||
|
/* get the variable name preceding the equal (=) sign */
|
||||||
|
if((eqpos = strchr(pairlist[i], '=')) != NULL) {
|
||||||
|
*eqpos = '\0';
|
||||||
|
cgivars[i * 2 + 1] = strdup(eqpos + 1);
|
||||||
|
if(NULL == cgivars[ i * 2 + 1]) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for cgi value #%d.\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
unescape_cgi_input(cgivars[i * 2 + 1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cgivars[i * 2 + 1] = strdup("");
|
||||||
|
if(NULL == cgivars[ i * 2 + 1]) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for empty stringfor variable value #%d.\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
unescape_cgi_input(cgivars[i * 2 + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the variable value (or name/value of there was no real "pair" in the first place) */
|
||||||
|
cgivars[i * 2] = strdup(pairlist[i]);
|
||||||
|
if(NULL == cgivars[ i * 2]) {
|
||||||
|
printf("getcgivars(): Could not allocate memory for cgi name #%d.\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
unescape_cgi_input(cgivars[i * 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* terminate the name-value list */
|
||||||
|
cgivars[paircount * 2] = '\x0';
|
||||||
|
|
||||||
|
/* free allocated memory */
|
||||||
|
free(cgiinput);
|
||||||
|
for(i = 0; pairlist[i] != NULL; i++)
|
||||||
|
free(pairlist[i]);
|
||||||
|
free(pairlist);
|
||||||
|
|
||||||
|
/* sanitize the name-value strings */
|
||||||
|
sanitize_cgi_input(cgivars);
|
||||||
|
|
||||||
|
/* return the list of name-value strings */
|
||||||
|
return cgivars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the locale based on the HTTP_ACCEPT_LANGUAGE variable value sent by
|
||||||
|
the browser */
|
||||||
|
void process_language(char * accept_language) {
|
||||||
|
accept_languages *accept_langs = NULL;
|
||||||
|
int x;
|
||||||
|
char locale_string[ 64];
|
||||||
|
char * locale = NULL;
|
||||||
|
char * locale_failsafe[] = { "en_US.utf8", "POSIX", "C" };
|
||||||
|
|
||||||
|
if(accept_language != NULL) {
|
||||||
|
accept_langs = parse_accept_languages(accept_language);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(NULL != accept_langs) {
|
||||||
|
/* Sort the results */
|
||||||
|
qsort(accept_langs->languages, accept_langs->count,
|
||||||
|
sizeof(accept_langs->languages[ 0]), compare_accept_languages);
|
||||||
|
|
||||||
|
/* Try each language in order of priority */
|
||||||
|
for(x = 0; ((x < accept_langs->count) && (NULL == locale)); x++) {
|
||||||
|
snprintf(locale_string, sizeof(locale_string), "%s_%s.%s",
|
||||||
|
accept_langs->languages[ x]->language,
|
||||||
|
accept_langs->languages[ x]->locality, "utf8");
|
||||||
|
locale = setlocale(LC_CTYPE, locale_string);
|
||||||
|
if(NULL != locale) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free_accept_languages(accept_langs);
|
||||||
|
}
|
||||||
|
if(NULL == locale) { /* Still isn't set */
|
||||||
|
/* Try the fail safe locales */
|
||||||
|
for(x = 0; ((x < (sizeof(locale_failsafe) / sizeof(char *))) &&
|
||||||
|
(NULL == locale)); x++) {
|
||||||
|
locale = setlocale(LC_CTYPE, locale_failsafe[ x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
accept_languages * parse_accept_languages(char * acceptlang) {
|
||||||
|
char * langdup; /* Duplicate of accept language for parsing */
|
||||||
|
accept_languages *langs = NULL;
|
||||||
|
char * langtok; /* Language token (language + locality + q value) */
|
||||||
|
char * saveptr; /* Save state of tokenization */
|
||||||
|
char * qdelim; /* location of the delimiter ';q=' */
|
||||||
|
char * localitydelim; /* Delimiter for locality specifier */
|
||||||
|
int x;
|
||||||
|
char * stp;
|
||||||
|
|
||||||
|
/* If the browser did not pass an HTTP_ACCEPT_LANGUAGE variable, there
|
||||||
|
is not much we can do */
|
||||||
|
if(NULL == acceptlang) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Duplicate the browser supplied HTTP_ACCEPT_LANGUAGE variable */
|
||||||
|
if(NULL == (langdup = strdup(acceptlang))) {
|
||||||
|
printf("Unable to allocate memory for langdup\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the structure to contain the parsed HTTP_ACCEPT_LANGUAGE
|
||||||
|
information */
|
||||||
|
if(NULL == (langs = malloc(sizeof(accept_languages)))) {
|
||||||
|
printf("Unable to allocate memory for langs\n");
|
||||||
|
free(langdup);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
langs->count = 0;
|
||||||
|
langs->languages = (accept_language **)NULL;
|
||||||
|
|
||||||
|
/* Tokenize the HTTP_ACCEPT_LANGUAGE string */
|
||||||
|
langtok = strtok_r(langdup, ",", &saveptr);
|
||||||
|
while(langtok != NULL) {
|
||||||
|
/* Bump the count and allocate memory for structures */
|
||||||
|
langs->count++;
|
||||||
|
if(NULL == langs->languages) {
|
||||||
|
/* Adding first language */
|
||||||
|
if(NULL == (langs->languages =
|
||||||
|
malloc(langs->count * sizeof(accept_language *)))) {
|
||||||
|
printf("Unable to allocate memory for first language\n");
|
||||||
|
langs->count--;
|
||||||
|
free_accept_languages(langs);
|
||||||
|
free(langdup);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Adding additional language */
|
||||||
|
if(NULL == (langs->languages = realloc(langs->languages,
|
||||||
|
langs->count * sizeof(accept_language *)))) {
|
||||||
|
printf("Unable to allocate memory for additional language\n");
|
||||||
|
langs->count--;
|
||||||
|
free_accept_languages(langs);
|
||||||
|
free(langdup);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(NULL == (langs->languages[ langs->count - 1] =
|
||||||
|
malloc(sizeof(accept_language)))) {
|
||||||
|
printf("Unable to allocate memory for language\n");
|
||||||
|
langs->count--;
|
||||||
|
free_accept_languages(langs);
|
||||||
|
free(langdup);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
langs->languages[ langs->count - 1]->language = (char *)NULL;
|
||||||
|
langs->languages[ langs->count - 1]->locality = (char *)NULL;
|
||||||
|
langs->languages[ langs->count - 1]->q = 1.0;
|
||||||
|
|
||||||
|
/* Check to see if there is a q value */
|
||||||
|
qdelim = strstr(langtok, ACCEPT_LANGUAGE_Q_DELIMITER);
|
||||||
|
|
||||||
|
if(NULL != qdelim) { /* found a q value */
|
||||||
|
langs->languages[ langs->count - 1]->q =
|
||||||
|
strtod(qdelim + strlen(ACCEPT_LANGUAGE_Q_DELIMITER), NULL);
|
||||||
|
langtok[ qdelim - langtok] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check to see if there is a locality specifier */
|
||||||
|
if(NULL == (localitydelim = strchr(langtok, '-'))) {
|
||||||
|
localitydelim = strchr(langtok, '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(NULL != localitydelim) {
|
||||||
|
/* We have a locality delimiter, so copy it */
|
||||||
|
if(NULL == (langs->languages[ langs->count - 1]->locality =
|
||||||
|
strdup(localitydelim + 1))) {
|
||||||
|
printf("Unable to allocate memory for locality '%s'\n",
|
||||||
|
langtok);
|
||||||
|
free_accept_languages(langs);
|
||||||
|
free(langdup);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure it is upper case */
|
||||||
|
for(x = 0, stp = langs->languages[ langs->count - 1]->locality;
|
||||||
|
x < strlen(langs->languages[ langs->count - 1]->locality);
|
||||||
|
x++, stp++) {
|
||||||
|
*stp = toupper(*stp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then null out the delimiter so the language copy works */
|
||||||
|
*localitydelim = '\0';
|
||||||
|
}
|
||||||
|
if(NULL == (langs->languages[ langs->count - 1]->language =
|
||||||
|
strdup(langtok))) {
|
||||||
|
printf("Unable to allocate memory for language '%s'\n",
|
||||||
|
langtok);
|
||||||
|
free_accept_languages(langs);
|
||||||
|
free(langdup);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the next language token */
|
||||||
|
langtok = strtok_r(NULL, ",", &saveptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(langdup);
|
||||||
|
return langs;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compare_accept_languages(const void *p1, const void *p2) {
|
||||||
|
accept_language * lang1 = *(accept_language **)p1;
|
||||||
|
accept_language * lang2 = *(accept_language **)p2;
|
||||||
|
|
||||||
|
if(lang1->q == lang2->q) {
|
||||||
|
if(((NULL == lang1->locality) && (NULL == lang2->locality)) ||
|
||||||
|
((NULL != lang1->locality) && (NULL != lang2->locality))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(NULL != lang1->locality) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else { /* NULL != lang2->locality */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return(lang2->q > lang1->q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void free_accept_languages(accept_languages * langs) {
|
||||||
|
int x;
|
||||||
|
|
||||||
|
if(NULL == langs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(x = 0; x < langs->count; x++) {
|
||||||
|
if(NULL != langs->languages[ x]) {
|
||||||
|
if(langs->languages[ x]->language != NULL) {
|
||||||
|
free(langs->languages[ x]->language);
|
||||||
|
}
|
||||||
|
if(langs->languages[ x]->locality != NULL) {
|
||||||
|
free(langs->languages[ x]->locality);
|
||||||
|
}
|
||||||
|
free(langs->languages[ x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(langs->languages != NULL) {
|
||||||
|
free(langs->languages);
|
||||||
|
}
|
||||||
|
free(langs);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free() memory allocated to storing the CGI variables */
|
||||||
|
void free_cgivars(char **cgivars) {
|
||||||
|
register int x;
|
||||||
|
|
||||||
|
for(x = 0; cgivars[x] != '\x0'; x++)
|
||||||
|
free(cgivars[x]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
2481
cgi/histogram.c
Normal file
971
cgi/history.c
Normal file
@ -0,0 +1,971 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* HISTORY.C - Nagios History CGI
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 06-23-2008
|
||||||
|
*
|
||||||
|
* This CGI program will display the history for the specified host.
|
||||||
|
* If no host is specified, the history for all hosts will be displayed.
|
||||||
|
*
|
||||||
|
* 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 "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
|
||||||
|
#include "../include/getcgi.h"
|
||||||
|
#include "../include/cgiutils.h"
|
||||||
|
#include "../include/cgiauth.h"
|
||||||
|
|
||||||
|
#define DISPLAY_HOSTS 0
|
||||||
|
#define DISPLAY_SERVICES 1
|
||||||
|
|
||||||
|
#define SERVICE_HISTORY 0
|
||||||
|
#define HOST_HISTORY 1
|
||||||
|
#define SERVICE_FLAPPING_HISTORY 2
|
||||||
|
#define HOST_FLAPPING_HISTORY 3
|
||||||
|
#define SERVICE_DOWNTIME_HISTORY 4
|
||||||
|
#define HOST_DOWNTIME_HISTORY 5
|
||||||
|
|
||||||
|
#define STATE_ALL 0
|
||||||
|
#define STATE_SOFT 1
|
||||||
|
#define STATE_HARD 2
|
||||||
|
|
||||||
|
void get_history(void);
|
||||||
|
|
||||||
|
void document_header(int);
|
||||||
|
void document_footer(void);
|
||||||
|
int process_cgivars(void);
|
||||||
|
|
||||||
|
extern char main_config_file[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_html_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_images_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
extern int log_rotation_method;
|
||||||
|
|
||||||
|
extern int enable_splunk_integration;
|
||||||
|
|
||||||
|
authdata current_authdata;
|
||||||
|
|
||||||
|
char log_file_to_use[MAX_FILENAME_LENGTH];
|
||||||
|
int log_archive = 0;
|
||||||
|
|
||||||
|
int show_all_hosts = TRUE;
|
||||||
|
char *host_name = "all";
|
||||||
|
char *svc_description = "";
|
||||||
|
int display_type = DISPLAY_HOSTS;
|
||||||
|
int use_lifo = TRUE;
|
||||||
|
|
||||||
|
int history_options = HISTORY_ALL;
|
||||||
|
int state_options = STATE_ALL;
|
||||||
|
|
||||||
|
int embedded = FALSE;
|
||||||
|
int display_header = TRUE;
|
||||||
|
int display_frills = TRUE;
|
||||||
|
int display_timebreaks = TRUE;
|
||||||
|
int display_system_messages = TRUE;
|
||||||
|
int display_flapping_alerts = TRUE;
|
||||||
|
int display_downtime_alerts = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int result = OK;
|
||||||
|
char temp_buffer[MAX_INPUT_BUFFER];
|
||||||
|
char temp_buffer2[MAX_INPUT_BUFFER];
|
||||||
|
|
||||||
|
/* get the variables passed to us */
|
||||||
|
process_cgivars();
|
||||||
|
|
||||||
|
/* reset internal CGI variables */
|
||||||
|
reset_cgi_vars();
|
||||||
|
|
||||||
|
/* read the CGI configuration file */
|
||||||
|
result = read_cgi_config_file(get_cgi_config_location());
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
cgi_config_file_error(get_cgi_config_location());
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the main configuration file */
|
||||||
|
result = read_main_config_file(main_config_file);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
main_config_file_error(main_config_file);
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read all object configuration data */
|
||||||
|
result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
object_data_error();
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
document_header(TRUE);
|
||||||
|
|
||||||
|
/* get authentication information */
|
||||||
|
get_authentication_information(¤t_authdata);
|
||||||
|
|
||||||
|
/* determine what log file we should be using */
|
||||||
|
get_log_archive_to_use(log_archive, log_file_to_use, (int)sizeof(log_file_to_use));
|
||||||
|
|
||||||
|
if(display_header == TRUE) {
|
||||||
|
|
||||||
|
/* begin top table */
|
||||||
|
printf("<table border=0 width=100%%>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
|
||||||
|
/* left column of the first row */
|
||||||
|
printf("<td align=left valign=top width=33%%>\n");
|
||||||
|
|
||||||
|
if(display_type == DISPLAY_SERVICES)
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Alert History");
|
||||||
|
else if(show_all_hosts == TRUE)
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Alert History");
|
||||||
|
else
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Alert History");
|
||||||
|
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
|
||||||
|
display_info_table(temp_buffer, FALSE, ¤t_authdata);
|
||||||
|
|
||||||
|
printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
|
||||||
|
printf("<TR><TD CLASS='linkBox'>\n");
|
||||||
|
if(display_type == DISPLAY_HOSTS) {
|
||||||
|
printf("<A HREF='%s?host=%s'>View Status Detail For %s</A><BR />\n", STATUS_CGI, (show_all_hosts == TRUE) ? "all" : url_encode(host_name), (show_all_hosts == TRUE) ? "All Hosts" : "This Host");
|
||||||
|
printf("<A HREF='%s?host=%s'>View Notifications For %s</A><BR />\n", NOTIFICATIONS_CGI, (show_all_hosts == TRUE) ? "all" : url_encode(host_name), (show_all_hosts == TRUE) ? "All Hosts" : "This Host");
|
||||||
|
#ifdef USE_TRENDS
|
||||||
|
if(show_all_hosts == FALSE)
|
||||||
|
printf("<A HREF='%s?host=%s'>View Trends For This Host</A>\n", TRENDS_CGI, url_encode(host_name));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("<A HREF='%s?host=%s&", NOTIFICATIONS_CGI, url_encode(host_name));
|
||||||
|
printf("service=%s'>View Notifications For This Service</A><BR />\n", url_encode(svc_description));
|
||||||
|
#ifdef USE_TRENDS
|
||||||
|
printf("<A HREF='%s?host=%s&", TRENDS_CGI, url_encode(host_name));
|
||||||
|
printf("service=%s'>View Trends For This Service</A><BR />\n", url_encode(svc_description));
|
||||||
|
#endif
|
||||||
|
printf("<A HREF='%s?host=%s'>View History For This Host</A>\n", HISTORY_CGI, url_encode(host_name));
|
||||||
|
}
|
||||||
|
printf("</TD></TR>\n");
|
||||||
|
printf("</TABLE>\n");
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
|
||||||
|
/* middle column of top row */
|
||||||
|
printf("<td align=center valign=top width=33%%>\n");
|
||||||
|
|
||||||
|
printf("<DIV ALIGN=CENTER CLASS='dataTitle'>\n");
|
||||||
|
if(display_type == DISPLAY_SERVICES)
|
||||||
|
printf("Service '%s' On Host '%s'", svc_description, host_name);
|
||||||
|
else if(show_all_hosts == TRUE)
|
||||||
|
printf("All Hosts and Services");
|
||||||
|
else
|
||||||
|
printf("Host '%s'", host_name);
|
||||||
|
printf("</DIV>\n");
|
||||||
|
printf("<BR />\n");
|
||||||
|
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%shost=%s&type=%d&statetype=%d&", HISTORY_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "", url_encode(host_name), history_options, state_options);
|
||||||
|
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
|
||||||
|
if(display_type == DISPLAY_SERVICES) {
|
||||||
|
snprintf(temp_buffer2, sizeof(temp_buffer2) - 1, "service=%s&", url_encode(svc_description));
|
||||||
|
temp_buffer2[sizeof(temp_buffer2) - 1] = '\x0';
|
||||||
|
strncat(temp_buffer, temp_buffer2, sizeof(temp_buffer) - strlen(temp_buffer) - 1);
|
||||||
|
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
|
||||||
|
}
|
||||||
|
display_nav_table(temp_buffer, log_archive);
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
|
||||||
|
/* right hand column of top row */
|
||||||
|
printf("<td align=right valign=top width=33%%>\n");
|
||||||
|
|
||||||
|
printf("<form method=\"GET\" action=\"%s\">\n", HISTORY_CGI);
|
||||||
|
printf("<table border=0 CLASS='optBox'>\n");
|
||||||
|
printf("<input type='hidden' name='host' value='%s'>\n", (show_all_hosts == TRUE) ? "all" : escape_string(host_name));
|
||||||
|
if(display_type == DISPLAY_SERVICES)
|
||||||
|
printf("<input type='hidden' name='service' value='%s'>\n", escape_string(svc_description));
|
||||||
|
printf("<input type='hidden' name='archive' value='%d'>\n", log_archive);
|
||||||
|
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left CLASS='optBoxItem'>State type options:</td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left CLASS='optBoxItem'><select name='statetype'>\n");
|
||||||
|
printf("<option value=%d %s>All state types</option>\n", STATE_ALL, (state_options == STATE_ALL) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Soft states</option>\n", STATE_SOFT, (state_options == STATE_SOFT) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Hard states</option>\n", STATE_HARD, (state_options == STATE_HARD) ? "selected" : "");
|
||||||
|
printf("</select></td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left CLASS='optBoxItem'>History detail level for ");
|
||||||
|
if(display_type == DISPLAY_HOSTS)
|
||||||
|
printf("%s host%s", (show_all_hosts == TRUE) ? "all" : "this", (show_all_hosts == TRUE) ? "s" : "");
|
||||||
|
else
|
||||||
|
printf("service");
|
||||||
|
printf(":</td>\n");
|
||||||
|
printf("</tr>\n")
|
||||||
|
;
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left CLASS='optBoxItem'><select name='type'>\n");
|
||||||
|
if(display_type == DISPLAY_HOSTS)
|
||||||
|
printf("<option value=%d %s>All alerts</option>\n", HISTORY_ALL, (history_options == HISTORY_ALL) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>All service alerts</option>\n", HISTORY_SERVICE_ALL, (history_options == HISTORY_SERVICE_ALL) ? "selected" : "");
|
||||||
|
if(display_type == DISPLAY_HOSTS)
|
||||||
|
printf("<option value=%d %s>All host alerts</option>\n", HISTORY_HOST_ALL, (history_options == HISTORY_HOST_ALL) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service warning</option>\n", HISTORY_SERVICE_WARNING, (history_options == HISTORY_SERVICE_WARNING) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service unknown</option>\n", HISTORY_SERVICE_UNKNOWN, (history_options == HISTORY_SERVICE_UNKNOWN) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service critical</option>\n", HISTORY_SERVICE_CRITICAL, (history_options == HISTORY_SERVICE_CRITICAL) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service recovery</option>\n", HISTORY_SERVICE_RECOVERY, (history_options == HISTORY_SERVICE_RECOVERY) ? "selected" : "");
|
||||||
|
if(display_type == DISPLAY_HOSTS) {
|
||||||
|
printf("<option value=%d %s>Host down</option>\n", HISTORY_HOST_DOWN, (history_options == HISTORY_HOST_DOWN) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Host unreachable</option>\n", HISTORY_HOST_UNREACHABLE, (history_options == HISTORY_HOST_UNREACHABLE) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Host recovery</option>\n", HISTORY_HOST_RECOVERY, (history_options == HISTORY_HOST_RECOVERY) ? "selected" : "");
|
||||||
|
}
|
||||||
|
printf("</select></td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='noflapping' %s> Hide Flapping Alerts</td>", (display_flapping_alerts == FALSE) ? "checked" : "");
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='nodowntime' %s> Hide Downtime Alerts</td>", (display_downtime_alerts == FALSE) ? "checked" : "");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='nosystem' %s> Hide Process Messages</td>", (display_system_messages == FALSE) ? "checked" : "");
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='oldestfirst' %s> Older Entries First</td>", (use_lifo == FALSE) ? "checked" : "");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left CLASS='optBoxItem'><input type='submit' value='Update'></td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
/* display context-sensitive help */
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=right>\n");
|
||||||
|
display_context_help(CONTEXTHELP_HISTORY);
|
||||||
|
printf("</td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
printf("</table>\n");
|
||||||
|
printf("</form>\n");
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* end of top table */
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("</table>\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* display history */
|
||||||
|
get_history();
|
||||||
|
|
||||||
|
document_footer();
|
||||||
|
|
||||||
|
/* free allocated memory */
|
||||||
|
free_memory();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void document_header(int use_stylesheet) {
|
||||||
|
char date_time[MAX_DATETIME_LENGTH];
|
||||||
|
time_t current_time;
|
||||||
|
time_t expire_time;
|
||||||
|
|
||||||
|
printf("Cache-Control: no-store\r\n");
|
||||||
|
printf("Pragma: no-cache\r\n");
|
||||||
|
|
||||||
|
time(¤t_time);
|
||||||
|
get_time_string(¤t_time, date_time, sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Last-Modified: %s\r\n", date_time);
|
||||||
|
|
||||||
|
expire_time = (time_t)0L;
|
||||||
|
get_time_string(&expire_time, date_time, sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Expires: %s\r\n", date_time);
|
||||||
|
|
||||||
|
printf("Content-type: text/html\r\n\r\n");
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("<html>\n");
|
||||||
|
printf("<head>\n");
|
||||||
|
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
|
||||||
|
printf("<title>\n");
|
||||||
|
printf("Nagios History\n");
|
||||||
|
printf("</title>\n");
|
||||||
|
|
||||||
|
if(use_stylesheet == TRUE) {
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, COMMON_CSS);
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, HISTORY_CSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</head>\n");
|
||||||
|
printf("<BODY CLASS='history'>\n");
|
||||||
|
|
||||||
|
/* include user SSI header */
|
||||||
|
include_ssi_files(HISTORY_CGI, SSI_HEADER);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void document_footer(void) {
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* include user SSI footer */
|
||||||
|
include_ssi_files(HISTORY_CGI, SSI_FOOTER);
|
||||||
|
|
||||||
|
printf("</body>\n");
|
||||||
|
printf("</html>\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int process_cgivars(void) {
|
||||||
|
char **variables;
|
||||||
|
int error = FALSE;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
variables = getcgivars();
|
||||||
|
|
||||||
|
for(x = 0; variables[x] != NULL; x++) {
|
||||||
|
|
||||||
|
/* do some basic length checking on the variable identifier to prevent buffer overflows */
|
||||||
|
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* we found the host argument */
|
||||||
|
else if(!strcmp(variables[x], "host")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((host_name = (char *)strdup(variables[x])) == NULL)
|
||||||
|
host_name = "";
|
||||||
|
strip_html_brackets(host_name);
|
||||||
|
|
||||||
|
display_type = DISPLAY_HOSTS;
|
||||||
|
|
||||||
|
if(!strcmp(host_name, "all"))
|
||||||
|
show_all_hosts = TRUE;
|
||||||
|
else
|
||||||
|
show_all_hosts = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the service argument */
|
||||||
|
else if(!strcmp(variables[x], "service")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((svc_description = (char *)strdup(variables[x])) == NULL)
|
||||||
|
svc_description = "";
|
||||||
|
strip_html_brackets(svc_description);
|
||||||
|
|
||||||
|
display_type = DISPLAY_SERVICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* we found the history type argument */
|
||||||
|
else if(!strcmp(variables[x], "type")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
history_options = atoi(variables[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the history state type argument */
|
||||||
|
else if(!strcmp(variables[x], "statetype")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_options = atoi(variables[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* we found the log archive argument */
|
||||||
|
else if(!strcmp(variables[x], "archive")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_archive = atoi(variables[x]);
|
||||||
|
if(log_archive < 0)
|
||||||
|
log_archive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the order argument */
|
||||||
|
else if(!strcmp(variables[x], "oldestfirst")) {
|
||||||
|
use_lifo = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the embed option */
|
||||||
|
else if(!strcmp(variables[x], "embedded"))
|
||||||
|
embedded = TRUE;
|
||||||
|
|
||||||
|
/* we found the noheader option */
|
||||||
|
else if(!strcmp(variables[x], "noheader"))
|
||||||
|
display_header = FALSE;
|
||||||
|
|
||||||
|
/* we found the nofrills option */
|
||||||
|
else if(!strcmp(variables[x], "nofrills"))
|
||||||
|
display_frills = FALSE;
|
||||||
|
|
||||||
|
/* we found the notimebreaks option */
|
||||||
|
else if(!strcmp(variables[x], "notimebreaks"))
|
||||||
|
display_timebreaks = FALSE;
|
||||||
|
|
||||||
|
/* we found the no system messages option */
|
||||||
|
else if(!strcmp(variables[x], "nosystem"))
|
||||||
|
display_system_messages = FALSE;
|
||||||
|
|
||||||
|
/* we found the no flapping alerts option */
|
||||||
|
else if(!strcmp(variables[x], "noflapping"))
|
||||||
|
display_flapping_alerts = FALSE;
|
||||||
|
|
||||||
|
/* we found the no downtime alerts option */
|
||||||
|
else if(!strcmp(variables[x], "nodowntime"))
|
||||||
|
display_downtime_alerts = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory allocated to the CGI variables */
|
||||||
|
free_cgivars(variables);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void get_history(void) {
|
||||||
|
mmapfile *thefile = NULL;
|
||||||
|
char image[MAX_INPUT_BUFFER];
|
||||||
|
char image_alt[MAX_INPUT_BUFFER];
|
||||||
|
char *input = NULL;
|
||||||
|
char *input2 = NULL;
|
||||||
|
char match1[MAX_INPUT_BUFFER];
|
||||||
|
char match2[MAX_INPUT_BUFFER];
|
||||||
|
int found_line = FALSE;
|
||||||
|
int system_message = FALSE;
|
||||||
|
int display_line = FALSE;
|
||||||
|
time_t t;
|
||||||
|
char date_time[MAX_DATETIME_LENGTH];
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
int history_type = SERVICE_HISTORY;
|
||||||
|
int history_detail_type = HISTORY_SERVICE_CRITICAL;
|
||||||
|
char *entry_host_name = NULL;
|
||||||
|
char *entry_service_desc = NULL;
|
||||||
|
host *temp_host = NULL;
|
||||||
|
service *temp_service = NULL;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
char last_message_date[MAX_INPUT_BUFFER] = "";
|
||||||
|
char current_message_date[MAX_INPUT_BUFFER] = "";
|
||||||
|
struct tm *time_ptr = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if(use_lifo == TRUE) {
|
||||||
|
result = read_file_into_lifo(log_file_to_use);
|
||||||
|
if(result != LIFO_OK) {
|
||||||
|
if(result == LIFO_ERROR_MEMORY) {
|
||||||
|
printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying history in natural order...</DIV></P>\n");
|
||||||
|
}
|
||||||
|
else if(result == LIFO_ERROR_FILE) {
|
||||||
|
printf("<HR><P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P><HR>", log_file_to_use);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
use_lifo = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_lifo == FALSE) {
|
||||||
|
|
||||||
|
if((thefile = mmap_fopen(log_file_to_use)) == NULL) {
|
||||||
|
printf("<HR><P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P><HR>", log_file_to_use);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("<P><DIV CLASS='logEntries'>\n");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
my_free(input);
|
||||||
|
my_free(input2);
|
||||||
|
|
||||||
|
if(use_lifo == TRUE) {
|
||||||
|
if((input = pop_lifo()) == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if((input = mmap_fgets(thefile)) == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strip(input);
|
||||||
|
|
||||||
|
strcpy(image, "");
|
||||||
|
strcpy(image_alt, "");
|
||||||
|
system_message = FALSE;
|
||||||
|
|
||||||
|
if((input2 = (char *)strdup(input)) == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* service state alerts */
|
||||||
|
if(strstr(input, "SERVICE ALERT:")) {
|
||||||
|
|
||||||
|
history_type = SERVICE_HISTORY;
|
||||||
|
|
||||||
|
/* get host and service names */
|
||||||
|
temp_buffer = my_strtok(input2, "]");
|
||||||
|
temp_buffer = my_strtok(NULL, ":");
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_host_name = strdup(temp_buffer + 1);
|
||||||
|
else
|
||||||
|
entry_host_name = NULL;
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_service_desc = strdup(temp_buffer);
|
||||||
|
else
|
||||||
|
entry_service_desc = NULL;
|
||||||
|
|
||||||
|
if(strstr(input, ";CRITICAL;")) {
|
||||||
|
strncpy(image, CRITICAL_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, CRITICAL_ICON_ALT, sizeof(image_alt));
|
||||||
|
history_detail_type = HISTORY_SERVICE_CRITICAL;
|
||||||
|
}
|
||||||
|
else if(strstr(input, ";WARNING;")) {
|
||||||
|
strncpy(image, WARNING_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, WARNING_ICON_ALT, sizeof(image_alt));
|
||||||
|
history_detail_type = HISTORY_SERVICE_WARNING;
|
||||||
|
}
|
||||||
|
else if(strstr(input, ";UNKNOWN;")) {
|
||||||
|
strncpy(image, UNKNOWN_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, UNKNOWN_ICON_ALT, sizeof(image_alt));
|
||||||
|
history_detail_type = HISTORY_SERVICE_UNKNOWN;
|
||||||
|
}
|
||||||
|
else if(strstr(input, ";RECOVERY;") || strstr(input, ";OK;")) {
|
||||||
|
strncpy(image, OK_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, OK_ICON_ALT, sizeof(image_alt));
|
||||||
|
history_detail_type = HISTORY_SERVICE_RECOVERY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* service flapping alerts */
|
||||||
|
else if(strstr(input, "SERVICE FLAPPING ALERT:")) {
|
||||||
|
|
||||||
|
if(display_flapping_alerts == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
history_type = SERVICE_FLAPPING_HISTORY;
|
||||||
|
|
||||||
|
/* get host and service names */
|
||||||
|
temp_buffer = my_strtok(input2, "]");
|
||||||
|
temp_buffer = my_strtok(NULL, ":");
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_host_name = strdup(temp_buffer + 1);
|
||||||
|
else
|
||||||
|
entry_host_name = NULL;
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_service_desc = strdup(temp_buffer);
|
||||||
|
else
|
||||||
|
entry_service_desc = NULL;
|
||||||
|
|
||||||
|
strncpy(image, FLAPPING_ICON, sizeof(image));
|
||||||
|
|
||||||
|
if(strstr(input, ";STARTED;"))
|
||||||
|
strncpy(image_alt, "Service started flapping", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";STOPPED;"))
|
||||||
|
strncpy(image_alt, "Service stopped flapping", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";DISABLED;"))
|
||||||
|
strncpy(image_alt, "Service flap detection disabled", sizeof(image_alt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* service downtime alerts */
|
||||||
|
else if(strstr(input, "SERVICE DOWNTIME ALERT:")) {
|
||||||
|
|
||||||
|
if(display_downtime_alerts == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
history_type = SERVICE_DOWNTIME_HISTORY;
|
||||||
|
|
||||||
|
/* get host and service names */
|
||||||
|
temp_buffer = my_strtok(input2, "]");
|
||||||
|
temp_buffer = my_strtok(NULL, ":");
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_host_name = strdup(temp_buffer + 1);
|
||||||
|
else
|
||||||
|
entry_host_name = NULL;
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_service_desc = strdup(temp_buffer);
|
||||||
|
else
|
||||||
|
entry_service_desc = NULL;
|
||||||
|
|
||||||
|
strncpy(image, SCHEDULED_DOWNTIME_ICON, sizeof(image));
|
||||||
|
|
||||||
|
if(strstr(input, ";STARTED;"))
|
||||||
|
strncpy(image_alt, "Service entered a period of scheduled downtime", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";STOPPED;"))
|
||||||
|
strncpy(image_alt, "Service exited from a period of scheduled downtime", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";CANCELLED;"))
|
||||||
|
strncpy(image_alt, "Service scheduled downtime has been cancelled", sizeof(image_alt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* host state alerts */
|
||||||
|
else if(strstr(input, "HOST ALERT:")) {
|
||||||
|
|
||||||
|
history_type = HOST_HISTORY;
|
||||||
|
|
||||||
|
/* get host name */
|
||||||
|
temp_buffer = my_strtok(input2, "]");
|
||||||
|
temp_buffer = my_strtok(NULL, ":");
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_host_name = strdup(temp_buffer + 1);
|
||||||
|
else
|
||||||
|
entry_host_name = NULL;
|
||||||
|
|
||||||
|
if(strstr(input, ";DOWN;")) {
|
||||||
|
strncpy(image, HOST_DOWN_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, HOST_DOWN_ICON_ALT, sizeof(image_alt));
|
||||||
|
history_detail_type = HISTORY_HOST_DOWN;
|
||||||
|
}
|
||||||
|
else if(strstr(input, ";UNREACHABLE;")) {
|
||||||
|
strncpy(image, HOST_UNREACHABLE_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, HOST_UNREACHABLE_ICON_ALT, sizeof(image_alt));
|
||||||
|
history_detail_type = HISTORY_HOST_UNREACHABLE;
|
||||||
|
}
|
||||||
|
else if(strstr(input, ";RECOVERY") || strstr(input, ";UP;")) {
|
||||||
|
strncpy(image, HOST_UP_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, HOST_UP_ICON_ALT, sizeof(image_alt));
|
||||||
|
history_detail_type = HISTORY_HOST_RECOVERY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* host flapping alerts */
|
||||||
|
else if(strstr(input, "HOST FLAPPING ALERT:")) {
|
||||||
|
|
||||||
|
if(display_flapping_alerts == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
history_type = HOST_FLAPPING_HISTORY;
|
||||||
|
|
||||||
|
/* get host name */
|
||||||
|
temp_buffer = my_strtok(input2, "]");
|
||||||
|
temp_buffer = my_strtok(NULL, ":");
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_host_name = strdup(temp_buffer + 1);
|
||||||
|
else
|
||||||
|
entry_host_name = NULL;
|
||||||
|
|
||||||
|
strncpy(image, FLAPPING_ICON, sizeof(image));
|
||||||
|
|
||||||
|
if(strstr(input, ";STARTED;"))
|
||||||
|
strncpy(image_alt, "Host started flapping", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";STOPPED;"))
|
||||||
|
strncpy(image_alt, "Host stopped flapping", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";DISABLED;"))
|
||||||
|
strncpy(image_alt, "Host flap detection disabled", sizeof(image_alt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* host downtime alerts */
|
||||||
|
else if(strstr(input, "HOST DOWNTIME ALERT:")) {
|
||||||
|
|
||||||
|
if(display_downtime_alerts == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
history_type = HOST_DOWNTIME_HISTORY;
|
||||||
|
|
||||||
|
/* get host name */
|
||||||
|
temp_buffer = my_strtok(input2, "]");
|
||||||
|
temp_buffer = my_strtok(NULL, ":");
|
||||||
|
temp_buffer = my_strtok(NULL, ";");
|
||||||
|
if(temp_buffer)
|
||||||
|
entry_host_name = strdup(temp_buffer + 1);
|
||||||
|
else
|
||||||
|
entry_host_name = NULL;
|
||||||
|
|
||||||
|
strncpy(image, SCHEDULED_DOWNTIME_ICON, sizeof(image));
|
||||||
|
|
||||||
|
if(strstr(input, ";STARTED;"))
|
||||||
|
strncpy(image_alt, "Host entered a period of scheduled downtime", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";STOPPED;"))
|
||||||
|
strncpy(image_alt, "Host exited from a period of scheduled downtime", sizeof(image_alt));
|
||||||
|
else if(strstr(input, ";CANCELLED;"))
|
||||||
|
strncpy(image_alt, "Host scheduled downtime has been cancelled", sizeof(image_alt));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(display_system_messages == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* program start */
|
||||||
|
else if(strstr(input, " starting...")) {
|
||||||
|
strncpy(image, START_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, START_ICON_ALT, sizeof(image_alt));
|
||||||
|
system_message = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* normal program termination */
|
||||||
|
else if(strstr(input, " shutting down...")) {
|
||||||
|
strncpy(image, STOP_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, STOP_ICON_ALT, sizeof(image_alt));
|
||||||
|
system_message = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* abnormal program termination */
|
||||||
|
else if(strstr(input, "Bailing out")) {
|
||||||
|
strncpy(image, STOP_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, STOP_ICON_ALT, sizeof(image_alt));
|
||||||
|
system_message = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* program restart */
|
||||||
|
else if(strstr(input, " restarting...")) {
|
||||||
|
strncpy(image, RESTART_ICON, sizeof(image));
|
||||||
|
strncpy(image_alt, RESTART_ICON_ALT, sizeof(image_alt));
|
||||||
|
system_message = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
image[sizeof(image) - 1] = '\x0';
|
||||||
|
image_alt[sizeof(image_alt) - 1] = '\x0';
|
||||||
|
|
||||||
|
/* get the timestamp */
|
||||||
|
temp_buffer = strtok(input, "]");
|
||||||
|
t = (temp_buffer == NULL) ? 0L : strtoul(temp_buffer + 1, NULL, 10);
|
||||||
|
|
||||||
|
time_ptr = localtime(&t);
|
||||||
|
strftime(current_message_date, sizeof(current_message_date), "%B %d, %Y %H:00\n", time_ptr);
|
||||||
|
current_message_date[sizeof(current_message_date) - 1] = '\x0';
|
||||||
|
|
||||||
|
get_time_string(&t, date_time, sizeof(date_time), SHORT_DATE_TIME);
|
||||||
|
strip(date_time);
|
||||||
|
|
||||||
|
temp_buffer = strtok(NULL, "\n");
|
||||||
|
|
||||||
|
if(strcmp(image, "")) {
|
||||||
|
|
||||||
|
display_line = FALSE;
|
||||||
|
|
||||||
|
if(system_message == TRUE)
|
||||||
|
display_line = TRUE;
|
||||||
|
|
||||||
|
else if(display_type == DISPLAY_HOSTS) {
|
||||||
|
|
||||||
|
if(history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) {
|
||||||
|
snprintf(match1, sizeof(match1),
|
||||||
|
" HOST ALERT: %s;", host_name);
|
||||||
|
snprintf(match2, sizeof(match2),
|
||||||
|
" SERVICE ALERT: %s;", host_name);
|
||||||
|
}
|
||||||
|
else if(history_type == HOST_FLAPPING_HISTORY || history_type == SERVICE_FLAPPING_HISTORY) {
|
||||||
|
snprintf(match1, sizeof(match1),
|
||||||
|
" HOST FLAPPING ALERT: %s;", host_name);
|
||||||
|
snprintf(match2, sizeof(match2),
|
||||||
|
" SERVICE FLAPPING ALERT: %s;", host_name);
|
||||||
|
}
|
||||||
|
else if(history_type == HOST_DOWNTIME_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY) {
|
||||||
|
snprintf(match1, sizeof(match1),
|
||||||
|
" HOST DOWNTIME ALERT: %s;", host_name);
|
||||||
|
snprintf(match2, sizeof(match2),
|
||||||
|
" SERVICE DOWNTIME ALERT: %s;", host_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(show_all_hosts == TRUE)
|
||||||
|
display_line = TRUE;
|
||||||
|
else if(strstr(temp_buffer, match1))
|
||||||
|
display_line = TRUE;
|
||||||
|
else if(strstr(temp_buffer, match2))
|
||||||
|
display_line = TRUE;
|
||||||
|
|
||||||
|
if(display_line == TRUE) {
|
||||||
|
if(history_options == HISTORY_ALL)
|
||||||
|
display_line = TRUE;
|
||||||
|
else if(history_options == HISTORY_HOST_ALL && (history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY))
|
||||||
|
display_line = TRUE;
|
||||||
|
else if(history_options == HISTORY_SERVICE_ALL && (history_type == SERVICE_HISTORY || history_type == SERVICE_FLAPPING_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY))
|
||||||
|
display_line = TRUE;
|
||||||
|
else if((history_type == HOST_HISTORY || history_type == SERVICE_HISTORY) && (history_detail_type & history_options))
|
||||||
|
display_line = TRUE;
|
||||||
|
else
|
||||||
|
display_line = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check alert state types */
|
||||||
|
if(display_line == TRUE && (history_type == HOST_HISTORY || history_type == SERVICE_HISTORY)) {
|
||||||
|
if(state_options == STATE_ALL)
|
||||||
|
display_line = TRUE;
|
||||||
|
else if((state_options & STATE_SOFT) && strstr(temp_buffer, ";SOFT;"))
|
||||||
|
display_line = TRUE;
|
||||||
|
else if((state_options & STATE_HARD) && strstr(temp_buffer, ";HARD;"))
|
||||||
|
display_line = TRUE;
|
||||||
|
else
|
||||||
|
display_line = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(display_type == DISPLAY_SERVICES) {
|
||||||
|
|
||||||
|
if(history_type == SERVICE_HISTORY)
|
||||||
|
snprintf(match1, sizeof(match1), " SERVICE ALERT: %s;%s;", host_name, svc_description);
|
||||||
|
else if(history_type == SERVICE_FLAPPING_HISTORY)
|
||||||
|
snprintf(match1, sizeof(match1), " SERVICE FLAPPING ALERT: %s;%s;", host_name, svc_description);
|
||||||
|
else if(history_type == SERVICE_DOWNTIME_HISTORY)
|
||||||
|
snprintf(match1, sizeof(match1), " SERVICE DOWNTIME ALERT: %s;%s;", host_name, svc_description);
|
||||||
|
|
||||||
|
if(strstr(temp_buffer, match1) && (history_type == SERVICE_HISTORY || history_type == SERVICE_FLAPPING_HISTORY || history_type == SERVICE_DOWNTIME_HISTORY))
|
||||||
|
display_line = TRUE;
|
||||||
|
|
||||||
|
if(display_line == TRUE) {
|
||||||
|
if(history_options == HISTORY_ALL || history_options == HISTORY_SERVICE_ALL)
|
||||||
|
display_line = TRUE;
|
||||||
|
else if(history_options & history_detail_type)
|
||||||
|
display_line = TRUE;
|
||||||
|
else
|
||||||
|
display_line = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check alert state type */
|
||||||
|
if(display_line == TRUE && history_type == SERVICE_HISTORY) {
|
||||||
|
|
||||||
|
if(state_options == STATE_ALL)
|
||||||
|
display_line = TRUE;
|
||||||
|
else if((state_options & STATE_SOFT) && strstr(temp_buffer, ";SOFT;"))
|
||||||
|
display_line = TRUE;
|
||||||
|
else if((state_options & STATE_HARD) && strstr(temp_buffer, ";HARD;"))
|
||||||
|
display_line = TRUE;
|
||||||
|
else
|
||||||
|
display_line = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* make sure user is authorized to view this host or service information */
|
||||||
|
if(system_message == FALSE) {
|
||||||
|
|
||||||
|
if(history_type == HOST_HISTORY || history_type == HOST_FLAPPING_HISTORY || history_type == HOST_DOWNTIME_HISTORY) {
|
||||||
|
temp_host = find_host(entry_host_name);
|
||||||
|
if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE)
|
||||||
|
display_line = FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temp_service = find_service(entry_host_name, entry_service_desc);
|
||||||
|
if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
|
||||||
|
display_line = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* display the entry if we should... */
|
||||||
|
if(display_line == TRUE) {
|
||||||
|
|
||||||
|
if(strcmp(last_message_date, current_message_date) != 0 && display_timebreaks == TRUE) {
|
||||||
|
printf("</DIV><BR CLEAR='all' />\n");
|
||||||
|
printf("<DIV CLASS='dateTimeBreak'>\n");
|
||||||
|
printf("<table border=0 width=95%%><tr>");
|
||||||
|
printf("<td width=40%%><hr width=100%%></td>");
|
||||||
|
printf("<td align=center CLASS='dateTimeBreak'>%s</td>", current_message_date);
|
||||||
|
printf("<td width=40%%><hr width=100%%></td>");
|
||||||
|
printf("</tr></table>\n");
|
||||||
|
printf("</DIV>\n");
|
||||||
|
printf("<BR CLEAR='all' /><DIV CLASS='logEntries'>\n");
|
||||||
|
strncpy(last_message_date, current_message_date, sizeof(last_message_date));
|
||||||
|
last_message_date[sizeof(last_message_date) - 1] = '\x0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(display_frills == TRUE)
|
||||||
|
printf("<img align='left' src='%s%s' alt='%s' title='%s' />", url_images_path, image, image_alt, image_alt);
|
||||||
|
printf("[%s] %s", date_time, html_encode(temp_buffer, FALSE));
|
||||||
|
if(enable_splunk_integration == TRUE) {
|
||||||
|
printf(" ");
|
||||||
|
display_splunk_generic_url(temp_buffer, 2);
|
||||||
|
}
|
||||||
|
printf("<br clear='all' />\n");
|
||||||
|
|
||||||
|
found_line = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
free(entry_host_name);
|
||||||
|
entry_host_name = NULL;
|
||||||
|
free(entry_service_desc);
|
||||||
|
entry_service_desc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</DIV></P>\n");
|
||||||
|
|
||||||
|
if(found_line == FALSE) {
|
||||||
|
printf("<HR>\n");
|
||||||
|
printf("<P><DIV CLASS='warningMessage'>No history information was found ");
|
||||||
|
if(display_type == DISPLAY_HOSTS)
|
||||||
|
printf("%s", (show_all_hosts == TRUE) ? "" : "for this host ");
|
||||||
|
else
|
||||||
|
printf("for this service ");
|
||||||
|
printf("in %s log file</DIV></P>", (log_archive == 0) ? "the current" : "this archived");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("<HR>\n");
|
||||||
|
|
||||||
|
my_free(input);
|
||||||
|
my_free(input2);
|
||||||
|
|
||||||
|
if(use_lifo == TRUE)
|
||||||
|
free_lifo_memory();
|
||||||
|
else
|
||||||
|
mmap_fclose(thefile);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
777
cgi/notifications.c
Normal file
@ -0,0 +1,777 @@
|
|||||||
|
/************************************************************************
|
||||||
|
*
|
||||||
|
* NOTIFICATIONS.C - Nagios Notifications CGI
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 01-08-2008
|
||||||
|
*
|
||||||
|
* This CGI program will display the notification events for
|
||||||
|
* a given host or contact or for all contacts/hosts.
|
||||||
|
*
|
||||||
|
* 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 "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
|
||||||
|
#include "../include/getcgi.h"
|
||||||
|
#include "../include/cgiutils.h"
|
||||||
|
#include "../include/cgiauth.h"
|
||||||
|
|
||||||
|
extern char main_config_file[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_html_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_images_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_docs_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
extern int log_rotation_method;
|
||||||
|
|
||||||
|
|
||||||
|
#define FIND_HOST 1
|
||||||
|
#define FIND_CONTACT 2
|
||||||
|
#define FIND_SERVICE 3
|
||||||
|
|
||||||
|
#define MAX_QUERYNAME_LENGTH 256
|
||||||
|
|
||||||
|
#define SERVICE_NOTIFICATION 0
|
||||||
|
#define HOST_NOTIFICATION 1
|
||||||
|
|
||||||
|
#define SERVICE_NOTIFICATION_STRING "] SERVICE NOTIFICATION:"
|
||||||
|
#define HOST_NOTIFICATION_STRING "] HOST NOTIFICATION:"
|
||||||
|
|
||||||
|
void display_notifications(void);
|
||||||
|
|
||||||
|
void document_header(int);
|
||||||
|
void document_footer(void);
|
||||||
|
int process_cgivars(void);
|
||||||
|
|
||||||
|
authdata current_authdata;
|
||||||
|
|
||||||
|
char log_file_to_use[MAX_FILENAME_LENGTH];
|
||||||
|
int log_archive = 0;
|
||||||
|
|
||||||
|
int query_type = FIND_HOST;
|
||||||
|
int find_all = TRUE;
|
||||||
|
char *query_contact_name = "";
|
||||||
|
char *query_host_name = "";
|
||||||
|
char *query_svc_description = "";
|
||||||
|
|
||||||
|
int notification_options = NOTIFICATION_ALL;
|
||||||
|
int use_lifo = TRUE;
|
||||||
|
|
||||||
|
int embedded = FALSE;
|
||||||
|
int display_header = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int result = OK;
|
||||||
|
char temp_buffer[MAX_INPUT_BUFFER];
|
||||||
|
char temp_buffer2[MAX_INPUT_BUFFER];
|
||||||
|
|
||||||
|
|
||||||
|
/* get the arguments passed in the URL */
|
||||||
|
process_cgivars();
|
||||||
|
|
||||||
|
/* reset internal variables */
|
||||||
|
reset_cgi_vars();
|
||||||
|
|
||||||
|
/* read the CGI configuration file */
|
||||||
|
result = read_cgi_config_file(get_cgi_config_location());
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
cgi_config_file_error(get_cgi_config_location());
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the main configuration file */
|
||||||
|
result = read_main_config_file(main_config_file);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
main_config_file_error(main_config_file);
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read all object configuration data */
|
||||||
|
result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
object_data_error();
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document_header(TRUE);
|
||||||
|
|
||||||
|
/* get authentication information */
|
||||||
|
get_authentication_information(¤t_authdata);
|
||||||
|
|
||||||
|
/* determine what log file we should use */
|
||||||
|
get_log_archive_to_use(log_archive, log_file_to_use, (int)sizeof(log_file_to_use));
|
||||||
|
|
||||||
|
|
||||||
|
if(display_header == TRUE) {
|
||||||
|
|
||||||
|
/* begin top table */
|
||||||
|
printf("<table border=0 width=100%%>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
|
||||||
|
/* left column of top row */
|
||||||
|
printf("<td align=left valign=top width=33%%>\n");
|
||||||
|
|
||||||
|
if(query_type == FIND_SERVICE)
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Service Notifications");
|
||||||
|
else if(query_type == FIND_HOST) {
|
||||||
|
if(find_all == TRUE)
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Notifications");
|
||||||
|
else
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Host Notifications");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "Contact Notifications");
|
||||||
|
display_info_table(temp_buffer, FALSE, ¤t_authdata);
|
||||||
|
|
||||||
|
if(query_type == FIND_HOST || query_type == FIND_SERVICE) {
|
||||||
|
printf("<TABLE BORDER=1 CELLPADDING=0 CELLSPACING=0 CLASS='linkBox'>\n");
|
||||||
|
printf("<TR><TD CLASS='linkBox'>\n");
|
||||||
|
if(query_type == FIND_HOST) {
|
||||||
|
printf("<A HREF='%s?host=%s'>View Status Detail For %s</A><BR>\n", STATUS_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name), (find_all == TRUE) ? "All Hosts" : "This Host");
|
||||||
|
printf("<A HREF='%s?host=%s'>View History For %s</A><BR>\n", HISTORY_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name), (find_all == TRUE) ? "All Hosts" : "This Host");
|
||||||
|
#ifdef USE_TRENDS
|
||||||
|
if(find_all == FALSE)
|
||||||
|
printf("<A HREF='%s?host=%s'>View Trends For This Host</A><BR>\n", TRENDS_CGI, url_encode(query_host_name));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(query_type == FIND_SERVICE) {
|
||||||
|
printf("<A HREF='%s?host=%s&", HISTORY_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name));
|
||||||
|
printf("service=%s'>View History For This Service</A><BR>\n", url_encode(query_svc_description));
|
||||||
|
#ifdef USE_TRENDS
|
||||||
|
printf("<A HREF='%s?host=%s&", TRENDS_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name));
|
||||||
|
printf("service=%s'>View Trends For This Service</A><BR>\n", url_encode(query_svc_description));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
printf("</TD></TR>\n");
|
||||||
|
printf("</TABLE>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
|
||||||
|
/* middle column of top row */
|
||||||
|
printf("<td align=center valign=top width=33%%>\n");
|
||||||
|
|
||||||
|
printf("<DIV ALIGN=CENTER CLASS='dataTitle'>\n");
|
||||||
|
if(query_type == FIND_SERVICE)
|
||||||
|
printf("Service '%s' On Host '%s'", query_svc_description, query_host_name);
|
||||||
|
else if(query_type == FIND_HOST) {
|
||||||
|
if(find_all == TRUE)
|
||||||
|
printf("All Hosts and Services");
|
||||||
|
else
|
||||||
|
printf("Host '%s'", query_host_name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(find_all == TRUE)
|
||||||
|
printf("All Contacts");
|
||||||
|
else
|
||||||
|
printf("Contact '%s'", query_contact_name);
|
||||||
|
}
|
||||||
|
printf("</DIV>\n");
|
||||||
|
printf("<BR>\n");
|
||||||
|
|
||||||
|
if(query_type == FIND_SERVICE) {
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%shost=%s&", NOTIFICATIONS_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "", url_encode(query_host_name));
|
||||||
|
snprintf(temp_buffer2, sizeof(temp_buffer2) - 1, "service=%s&type=%d&", url_encode(query_svc_description), notification_options);
|
||||||
|
strncat(temp_buffer, temp_buffer2, sizeof(temp_buffer) - strlen(temp_buffer) - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%s%s=%s&type=%d&", NOTIFICATIONS_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "", (query_type == FIND_HOST) ? "host" : "contact", (query_type == FIND_HOST) ? url_encode(query_host_name) : url_encode(query_contact_name), notification_options);
|
||||||
|
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
|
||||||
|
display_nav_table(temp_buffer, log_archive);
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
|
||||||
|
/* right hand column of top row */
|
||||||
|
printf("<td align=right valign=top width=33%%>\n");
|
||||||
|
|
||||||
|
printf("<form method='GET' action='%s'>\n", NOTIFICATIONS_CGI);
|
||||||
|
if(query_type == FIND_SERVICE) {
|
||||||
|
printf("<input type='hidden' name='host' value='%s'>\n", escape_string(query_host_name));
|
||||||
|
printf("<input type='hidden' name='service' value='%s'>\n", escape_string(query_svc_description));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("<input type='hidden' name='%s' value='%s'>\n", (query_type == FIND_HOST) ? "host" : "contact", (query_type == FIND_HOST) ? escape_string(query_host_name) : escape_string(query_contact_name));
|
||||||
|
printf("<input type='hidden' name='archive' value='%d'>\n", log_archive);
|
||||||
|
printf("<table border=0 CLASS='optBox'>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
if(query_type == FIND_SERVICE)
|
||||||
|
printf("<td align=left colspan=2 CLASS='optBoxItem'>Notification detail level for this service:</td>");
|
||||||
|
else
|
||||||
|
printf("<td align=left colspan=2 CLASS='optBoxItem'>Notification detail level for %s %s%s:</td>", (find_all == TRUE) ? "all" : "this", (query_type == FIND_HOST) ? "host" : "contact", (find_all == TRUE) ? "s" : "");
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left colspan=2 CLASS='optBoxItem'><select name='type'>\n");
|
||||||
|
printf("<option value=%d %s>All notifications\n", NOTIFICATION_ALL, (notification_options == NOTIFICATION_ALL) ? "selected" : "");
|
||||||
|
if(query_type != FIND_SERVICE) {
|
||||||
|
printf("<option value=%d %s>All service notifications\n", NOTIFICATION_SERVICE_ALL, (notification_options == NOTIFICATION_SERVICE_ALL) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>All host notifications\n", NOTIFICATION_HOST_ALL, (notification_options == NOTIFICATION_HOST_ALL) ? "selected" : "");
|
||||||
|
}
|
||||||
|
printf("<option value=%d %s>Service custom\n", NOTIFICATION_SERVICE_CUSTOM, (notification_options == NOTIFICATION_SERVICE_CUSTOM) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service acknowledgements\n", NOTIFICATION_SERVICE_ACK, (notification_options == NOTIFICATION_SERVICE_ACK) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service warning\n", NOTIFICATION_SERVICE_WARNING, (notification_options == NOTIFICATION_SERVICE_WARNING) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service unknown\n", NOTIFICATION_SERVICE_UNKNOWN, (notification_options == NOTIFICATION_SERVICE_UNKNOWN) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service critical\n", NOTIFICATION_SERVICE_CRITICAL, (notification_options == NOTIFICATION_SERVICE_CRITICAL) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service recovery\n", NOTIFICATION_SERVICE_RECOVERY, (notification_options == NOTIFICATION_SERVICE_RECOVERY) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Service flapping\n", NOTIFICATION_SERVICE_FLAP, (notification_options == NOTIFICATION_SERVICE_FLAP) ? "selected" : "");
|
||||||
|
if(query_type != FIND_SERVICE) {
|
||||||
|
printf("<option value=%d %s>Host custom\n", NOTIFICATION_HOST_CUSTOM, (notification_options == NOTIFICATION_HOST_CUSTOM) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Host acknowledgements\n", NOTIFICATION_HOST_ACK, (notification_options == NOTIFICATION_HOST_ACK) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Host down\n", NOTIFICATION_HOST_DOWN, (notification_options == NOTIFICATION_HOST_DOWN) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Host unreachable\n", NOTIFICATION_HOST_UNREACHABLE, (notification_options == NOTIFICATION_HOST_UNREACHABLE) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Host recovery\n", NOTIFICATION_HOST_RECOVERY, (notification_options == NOTIFICATION_HOST_RECOVERY) ? "selected" : "");
|
||||||
|
printf("<option value=%d %s>Host flapping\n", NOTIFICATION_HOST_FLAP, (notification_options == NOTIFICATION_HOST_FLAP) ? "selected" : "");
|
||||||
|
}
|
||||||
|
printf("</select></td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left CLASS='optBoxItem'>Older Entries First:</td>\n");
|
||||||
|
printf("<td></td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='oldestfirst' %s></td>", (use_lifo == FALSE) ? "checked" : "");
|
||||||
|
printf("<td align=right CLASS='optBoxItem'><input type='submit' value='Update'></td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
/* display context-sensitive help */
|
||||||
|
printf("<tr><td></td><td align=right valign=bottom>\n");
|
||||||
|
display_context_help(CONTEXTHELP_NOTIFICATIONS);
|
||||||
|
printf("</td></tr>\n");
|
||||||
|
|
||||||
|
printf("</table>\n");
|
||||||
|
printf("</form>\n");
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* end of top table */
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("</table>\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* display notifications */
|
||||||
|
display_notifications();
|
||||||
|
|
||||||
|
document_footer();
|
||||||
|
|
||||||
|
/* free allocated memory */
|
||||||
|
free_memory();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void document_header(int use_stylesheet) {
|
||||||
|
char date_time[MAX_DATETIME_LENGTH];
|
||||||
|
time_t current_time;
|
||||||
|
time_t expire_time;
|
||||||
|
|
||||||
|
printf("Cache-Control: no-store\r\n");
|
||||||
|
printf("Pragma: no-cache\r\n");
|
||||||
|
|
||||||
|
time(¤t_time);
|
||||||
|
get_time_string(¤t_time, date_time, (int)sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Last-Modified: %s\r\n", date_time);
|
||||||
|
|
||||||
|
expire_time = (time_t)0L;
|
||||||
|
get_time_string(&expire_time, date_time, (int)sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Expires: %s\r\n", date_time);
|
||||||
|
|
||||||
|
printf("Content-type: text/html\r\n\r\n");
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("<html>\n");
|
||||||
|
printf("<head>\n");
|
||||||
|
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
|
||||||
|
printf("<title>\n");
|
||||||
|
printf("Alert Notifications\n");
|
||||||
|
printf("</title>\n");
|
||||||
|
|
||||||
|
if(use_stylesheet == TRUE) {
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, COMMON_CSS);
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, NOTIFICATIONS_CSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</head>\n");
|
||||||
|
|
||||||
|
printf("<body CLASS='notifications'>\n");
|
||||||
|
|
||||||
|
/* include user SSI header */
|
||||||
|
include_ssi_files(NOTIFICATIONS_CGI, SSI_HEADER);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void document_footer(void) {
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* include user SSI footer */
|
||||||
|
include_ssi_files(NOTIFICATIONS_CGI, SSI_FOOTER);
|
||||||
|
|
||||||
|
printf("</body>\n");
|
||||||
|
printf("</html>\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int process_cgivars(void) {
|
||||||
|
char **variables;
|
||||||
|
int error = FALSE;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
variables = getcgivars();
|
||||||
|
|
||||||
|
for(x = 0; variables[x] != NULL; x++) {
|
||||||
|
|
||||||
|
/* do some basic length checking on the variable identifier to prevent buffer overflows */
|
||||||
|
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
|
||||||
|
x++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the host argument */
|
||||||
|
else if(!strcmp(variables[x], "host")) {
|
||||||
|
query_type = FIND_HOST;
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((query_host_name = strdup(variables[x])) == NULL)
|
||||||
|
query_host_name = "";
|
||||||
|
strip_html_brackets(query_host_name);
|
||||||
|
|
||||||
|
if(!strcmp(query_host_name, "all"))
|
||||||
|
find_all = TRUE;
|
||||||
|
else
|
||||||
|
find_all = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the contact argument */
|
||||||
|
else if(!strcmp(variables[x], "contact")) {
|
||||||
|
query_type = FIND_CONTACT;
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((query_contact_name = strdup(variables[x])) == NULL)
|
||||||
|
query_contact_name = "";
|
||||||
|
strip_html_brackets(query_contact_name);
|
||||||
|
|
||||||
|
if(!strcmp(query_contact_name, "all"))
|
||||||
|
find_all = TRUE;
|
||||||
|
else
|
||||||
|
find_all = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the service argument */
|
||||||
|
else if(!strcmp(variables[x], "service")) {
|
||||||
|
query_type = FIND_SERVICE;
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if((query_svc_description = strdup(variables[x])) == NULL)
|
||||||
|
query_svc_description = "";
|
||||||
|
strip_html_brackets(query_svc_description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the notification type argument */
|
||||||
|
else if(!strcmp(variables[x], "type")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
notification_options = atoi(variables[x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the log archive argument */
|
||||||
|
else if(!strcmp(variables[x], "archive")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_archive = atoi(variables[x]);
|
||||||
|
if(log_archive < 0)
|
||||||
|
log_archive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the order argument */
|
||||||
|
else if(!strcmp(variables[x], "oldestfirst")) {
|
||||||
|
use_lifo = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the embed option */
|
||||||
|
else if(!strcmp(variables[x], "embedded"))
|
||||||
|
embedded = TRUE;
|
||||||
|
|
||||||
|
/* we found the noheader option */
|
||||||
|
else if(!strcmp(variables[x], "noheader"))
|
||||||
|
display_header = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set some default values if not already set.
|
||||||
|
* Done here as they won't be set if variable
|
||||||
|
* not provided via cgi parameters
|
||||||
|
* Only required for hosts & contacts, not services
|
||||||
|
* as there is no service_name=all option
|
||||||
|
*/
|
||||||
|
if(query_type == FIND_HOST && strlen(query_host_name) == 0) {
|
||||||
|
query_host_name = "all";
|
||||||
|
find_all = TRUE;
|
||||||
|
}
|
||||||
|
if(query_type == FIND_CONTACT && strlen(query_contact_name) == 0) {
|
||||||
|
query_contact_name = "all";
|
||||||
|
find_all = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory allocated to the CGI variables */
|
||||||
|
free_cgivars(variables);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void display_notifications(void) {
|
||||||
|
mmapfile *thefile = NULL;
|
||||||
|
char *input = NULL;
|
||||||
|
char *temp_buffer;
|
||||||
|
char date_time[MAX_DATETIME_LENGTH];
|
||||||
|
char alert_level[MAX_INPUT_BUFFER];
|
||||||
|
char alert_level_class[MAX_INPUT_BUFFER];
|
||||||
|
char contact_name[MAX_INPUT_BUFFER];
|
||||||
|
char service_name[MAX_INPUT_BUFFER];
|
||||||
|
char host_name[MAX_INPUT_BUFFER];
|
||||||
|
char method_name[MAX_INPUT_BUFFER];
|
||||||
|
int show_entry;
|
||||||
|
int total_notifications;
|
||||||
|
int notification_type = SERVICE_NOTIFICATION;
|
||||||
|
int notification_detail_type = NOTIFICATION_SERVICE_CRITICAL;
|
||||||
|
int odd = 0;
|
||||||
|
time_t t;
|
||||||
|
host *temp_host;
|
||||||
|
service *temp_service;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if(use_lifo == TRUE) {
|
||||||
|
result = read_file_into_lifo(log_file_to_use);
|
||||||
|
if(result != LIFO_OK) {
|
||||||
|
if(result == LIFO_ERROR_MEMORY) {
|
||||||
|
printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying notifications in natural order...</DIV></P>");
|
||||||
|
}
|
||||||
|
else if(result == LIFO_ERROR_FILE) {
|
||||||
|
printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>", log_file_to_use);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
use_lifo = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_lifo == FALSE) {
|
||||||
|
|
||||||
|
if((thefile = mmap_fopen(log_file_to_use)) == NULL) {
|
||||||
|
printf("<P><DIV CLASS='errorMessage'>Error: Cannot open log file '%s' for reading!</DIV></P>", log_file_to_use);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("<p>\n");
|
||||||
|
printf("<div align='center'>\n");
|
||||||
|
|
||||||
|
printf("<table border=0 CLASS='notifications'>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<th CLASS='notifications'>Host</th>\n");
|
||||||
|
printf("<th CLASS='notifications'>Service</th>\n");
|
||||||
|
printf("<th CLASS='notifications'>Type</th>\n");
|
||||||
|
printf("<th CLASS='notifications'>Time</th>\n");
|
||||||
|
printf("<th CLASS='notifications'>Contact</th>\n");
|
||||||
|
printf("<th CLASS='notifications'>Notification Command</th>\n");
|
||||||
|
printf("<th CLASS='notifications'>Information</th>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
total_notifications = 0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
free(input);
|
||||||
|
|
||||||
|
if(use_lifo == TRUE) {
|
||||||
|
if((input = pop_lifo()) == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if((input = mmap_fgets(thefile)) == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strip(input);
|
||||||
|
|
||||||
|
/* see if this line contains the notification event string */
|
||||||
|
if(strstr(input, HOST_NOTIFICATION_STRING) || strstr(input, SERVICE_NOTIFICATION_STRING)) {
|
||||||
|
|
||||||
|
if(strstr(input, HOST_NOTIFICATION_STRING))
|
||||||
|
notification_type = HOST_NOTIFICATION;
|
||||||
|
else
|
||||||
|
notification_type = SERVICE_NOTIFICATION;
|
||||||
|
|
||||||
|
/* get the date/time */
|
||||||
|
temp_buffer = (char *)strtok(input, "]");
|
||||||
|
t = (time_t)(temp_buffer == NULL) ? 0L : strtoul(temp_buffer + 1, NULL, 10);
|
||||||
|
get_time_string(&t, date_time, (int)sizeof(date_time), SHORT_DATE_TIME);
|
||||||
|
strip(date_time);
|
||||||
|
|
||||||
|
/* get the contact name */
|
||||||
|
temp_buffer = (char *)strtok(NULL, ":");
|
||||||
|
temp_buffer = (char *)strtok(NULL, ";");
|
||||||
|
snprintf(contact_name, sizeof(contact_name), "%s", (temp_buffer == NULL) ? "" : temp_buffer + 1);
|
||||||
|
contact_name[sizeof(contact_name) - 1] = '\x0';
|
||||||
|
|
||||||
|
/* get the host name */
|
||||||
|
temp_buffer = (char *)strtok(NULL, ";");
|
||||||
|
snprintf(host_name, sizeof(host_name), "%s", (temp_buffer == NULL) ? "" : temp_buffer);
|
||||||
|
host_name[sizeof(host_name) - 1] = '\x0';
|
||||||
|
|
||||||
|
/* get the service name */
|
||||||
|
if(notification_type == SERVICE_NOTIFICATION) {
|
||||||
|
temp_buffer = (char *)strtok(NULL, ";");
|
||||||
|
snprintf(service_name, sizeof(service_name), "%s", (temp_buffer == NULL) ? "" : temp_buffer);
|
||||||
|
service_name[sizeof(service_name) - 1] = '\x0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the alert level */
|
||||||
|
temp_buffer = (char *)strtok(NULL, ";");
|
||||||
|
snprintf(alert_level, sizeof(alert_level), "%s", (temp_buffer == NULL) ? "" : temp_buffer);
|
||||||
|
alert_level[sizeof(alert_level) - 1] = '\x0';
|
||||||
|
|
||||||
|
if(notification_type == SERVICE_NOTIFICATION) {
|
||||||
|
|
||||||
|
if(!strcmp(alert_level, "CRITICAL")) {
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_CRITICAL;
|
||||||
|
strcpy(alert_level_class, "CRITICAL");
|
||||||
|
}
|
||||||
|
else if(!strcmp(alert_level, "WARNING")) {
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_WARNING;
|
||||||
|
strcpy(alert_level_class, "WARNING");
|
||||||
|
}
|
||||||
|
else if(!strcmp(alert_level, "RECOVERY") || !strcmp(alert_level, "OK")) {
|
||||||
|
strcpy(alert_level, "OK");
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_RECOVERY;
|
||||||
|
strcpy(alert_level_class, "OK");
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "CUSTOM (")) {
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_CUSTOM;
|
||||||
|
strcpy(alert_level_class, "CUSTOM");
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "ACKNOWLEDGEMENT (")) {
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_ACK;
|
||||||
|
strcpy(alert_level_class, "ACKNOWLEDGEMENT");
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "FLAPPINGSTART (")) {
|
||||||
|
strcpy(alert_level, "FLAPPING START");
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_FLAP;
|
||||||
|
strcpy(alert_level_class, "UNKNOWN");
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "FLAPPINGSTOP (")) {
|
||||||
|
strcpy(alert_level, "FLAPPING STOP");
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_FLAP;
|
||||||
|
strcpy(alert_level_class, "UNKNOWN");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strcpy(alert_level, "UNKNOWN");
|
||||||
|
notification_detail_type = NOTIFICATION_SERVICE_UNKNOWN;
|
||||||
|
strcpy(alert_level_class, "UNKNOWN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
if(!strcmp(alert_level, "DOWN")) {
|
||||||
|
strncpy(alert_level, "HOST DOWN", sizeof(alert_level));
|
||||||
|
strcpy(alert_level_class, "HOSTDOWN");
|
||||||
|
notification_detail_type = NOTIFICATION_HOST_DOWN;
|
||||||
|
}
|
||||||
|
else if(!strcmp(alert_level, "UNREACHABLE")) {
|
||||||
|
strncpy(alert_level, "HOST UNREACHABLE", sizeof(alert_level));
|
||||||
|
strcpy(alert_level_class, "HOSTUNREACHABLE");
|
||||||
|
notification_detail_type = NOTIFICATION_HOST_UNREACHABLE;
|
||||||
|
}
|
||||||
|
else if(!strcmp(alert_level, "RECOVERY") || !strcmp(alert_level, "UP")) {
|
||||||
|
strncpy(alert_level, "HOST UP", sizeof(alert_level));
|
||||||
|
strcpy(alert_level_class, "HOSTUP");
|
||||||
|
notification_detail_type = NOTIFICATION_HOST_RECOVERY;
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "CUSTOM (")) {
|
||||||
|
strcpy(alert_level_class, "HOSTCUSTOM");
|
||||||
|
notification_detail_type = NOTIFICATION_HOST_CUSTOM;
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "ACKNOWLEDGEMENT (")) {
|
||||||
|
strcpy(alert_level_class, "HOSTACKNOWLEDGEMENT");
|
||||||
|
notification_detail_type = NOTIFICATION_HOST_ACK;
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "FLAPPINGSTART (")) {
|
||||||
|
strcpy(alert_level, "FLAPPING START");
|
||||||
|
strcpy(alert_level_class, "UNKNOWN");
|
||||||
|
notification_detail_type = NOTIFICATION_HOST_FLAP;
|
||||||
|
}
|
||||||
|
else if(strstr(alert_level, "FLAPPINGSTOP (")) {
|
||||||
|
strcpy(alert_level, "FLAPPING STOP");
|
||||||
|
strcpy(alert_level_class, "UNKNOWN");
|
||||||
|
notification_detail_type = NOTIFICATION_HOST_FLAP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the method name */
|
||||||
|
temp_buffer = (char *)strtok(NULL, ";");
|
||||||
|
snprintf(method_name, sizeof(method_name), "%s", (temp_buffer == NULL) ? "" : temp_buffer);
|
||||||
|
method_name[sizeof(method_name) - 1] = '\x0';
|
||||||
|
|
||||||
|
/* move to the informational message */
|
||||||
|
temp_buffer = strtok(NULL, ";");
|
||||||
|
|
||||||
|
show_entry = FALSE;
|
||||||
|
|
||||||
|
/* if we're searching by contact, filter out unwanted contact */
|
||||||
|
if(query_type == FIND_CONTACT) {
|
||||||
|
if(find_all == TRUE)
|
||||||
|
show_entry = TRUE;
|
||||||
|
else if(!strcmp(query_contact_name, contact_name))
|
||||||
|
show_entry = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(query_type == FIND_HOST) {
|
||||||
|
if(find_all == TRUE)
|
||||||
|
show_entry = TRUE;
|
||||||
|
else if(!strcmp(query_host_name, host_name))
|
||||||
|
show_entry = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(query_type == FIND_SERVICE) {
|
||||||
|
if(!strcmp(query_host_name, host_name) && !strcmp(query_svc_description, service_name))
|
||||||
|
show_entry = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(show_entry == TRUE) {
|
||||||
|
if(notification_options == NOTIFICATION_ALL)
|
||||||
|
show_entry = TRUE;
|
||||||
|
else if(notification_options == NOTIFICATION_HOST_ALL && notification_type == HOST_NOTIFICATION)
|
||||||
|
show_entry = TRUE;
|
||||||
|
else if(notification_options == NOTIFICATION_SERVICE_ALL && notification_type == SERVICE_NOTIFICATION)
|
||||||
|
show_entry = TRUE;
|
||||||
|
else if(notification_detail_type & notification_options)
|
||||||
|
show_entry = TRUE;
|
||||||
|
else
|
||||||
|
show_entry = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure user has authorization to view this notification */
|
||||||
|
if(notification_type == HOST_NOTIFICATION) {
|
||||||
|
temp_host = find_host(host_name);
|
||||||
|
if(is_authorized_for_host(temp_host, ¤t_authdata) == FALSE)
|
||||||
|
show_entry = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temp_service = find_service(host_name, service_name);
|
||||||
|
if(is_authorized_for_service(temp_service, ¤t_authdata) == FALSE)
|
||||||
|
show_entry = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(show_entry == TRUE) {
|
||||||
|
|
||||||
|
total_notifications++;
|
||||||
|
|
||||||
|
if(odd) {
|
||||||
|
odd = 0;
|
||||||
|
printf("<tr CLASS='notificationsOdd'>\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
odd = 1;
|
||||||
|
printf("<tr CLASS='notificationsEven'>\n");
|
||||||
|
}
|
||||||
|
printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s'>%s</a></td>\n", (odd) ? "Even" : "Odd", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(host_name), host_name);
|
||||||
|
if(notification_type == SERVICE_NOTIFICATION) {
|
||||||
|
printf("<td CLASS='notifications%s'><a href='%s?type=%d&host=%s", (odd) ? "Even" : "Odd", EXTINFO_CGI, DISPLAY_SERVICE_INFO, url_encode(host_name));
|
||||||
|
printf("&service=%s'>%s</a></td>\n", url_encode(service_name), service_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("<td CLASS='notifications%s'>N/A</td>\n", (odd) ? "Even" : "Odd");
|
||||||
|
printf("<td CLASS='notifications%s'>%s</td>\n", alert_level_class, alert_level);
|
||||||
|
printf("<td CLASS='notifications%s'>%s</td>\n", (odd) ? "Even" : "Odd", date_time);
|
||||||
|
printf("<td CLASS='notifications%s'><a href='%s?type=contacts#%s'>%s</a></td>\n", (odd) ? "Even" : "Odd", CONFIG_CGI, url_encode(contact_name), contact_name);
|
||||||
|
printf("<td CLASS='notifications%s'><a href='%s?type=commands#%s'>%s</a></td>\n", (odd) ? "Even" : "Odd", CONFIG_CGI, url_encode(method_name), method_name);
|
||||||
|
printf("<td CLASS='notifications%s'>%s</td>\n", (odd) ? "Even" : "Odd", html_encode(temp_buffer, FALSE));
|
||||||
|
printf("</tr>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("</table>\n");
|
||||||
|
|
||||||
|
printf("</div>\n");
|
||||||
|
printf("</p>\n");
|
||||||
|
|
||||||
|
if(total_notifications == 0) {
|
||||||
|
printf("<P><DIV CLASS='errorMessage'>No notifications have been recorded");
|
||||||
|
if(find_all == FALSE) {
|
||||||
|
if(query_type == FIND_SERVICE)
|
||||||
|
printf(" for this service");
|
||||||
|
else if(query_type == FIND_CONTACT)
|
||||||
|
printf(" for this contact");
|
||||||
|
else
|
||||||
|
printf(" for this host");
|
||||||
|
}
|
||||||
|
printf(" in %s log file</DIV></P>", (log_archive == 0) ? "the current" : "this archived");
|
||||||
|
}
|
||||||
|
|
||||||
|
free(input);
|
||||||
|
|
||||||
|
if(use_lifo == TRUE)
|
||||||
|
free_lifo_memory();
|
||||||
|
else
|
||||||
|
mmap_fclose(thefile);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
697
cgi/outages.c
Normal file
@ -0,0 +1,697 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* OUTAGES.C - Nagios Network Outages CGI
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 01-08-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.
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
#include "../include/comments.h"
|
||||||
|
#include "../include/statusdata.h"
|
||||||
|
|
||||||
|
#include "../include/cgiutils.h"
|
||||||
|
#include "../include/getcgi.h"
|
||||||
|
#include "../include/cgiauth.h"
|
||||||
|
|
||||||
|
extern int refresh_rate;
|
||||||
|
extern time_t program_start;
|
||||||
|
|
||||||
|
extern host *host_list;
|
||||||
|
extern service *service_list;
|
||||||
|
extern hoststatus *hoststatus_list;
|
||||||
|
extern servicestatus *servicestatus_list;
|
||||||
|
|
||||||
|
extern char main_config_file[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_html_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_images_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_logo_images_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char log_file[MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
|
||||||
|
/* HOSTOUTAGE structure */
|
||||||
|
typedef struct hostoutage_struct {
|
||||||
|
host *hst;
|
||||||
|
int severity;
|
||||||
|
int affected_child_hosts;
|
||||||
|
int affected_child_services;
|
||||||
|
unsigned long monitored_time;
|
||||||
|
unsigned long time_up;
|
||||||
|
float percent_time_up;
|
||||||
|
unsigned long time_down;
|
||||||
|
float percent_time_down;
|
||||||
|
unsigned long time_unreachable;
|
||||||
|
float percent_time_unreachable;
|
||||||
|
struct hostoutage_struct *next;
|
||||||
|
} hostoutage;
|
||||||
|
|
||||||
|
|
||||||
|
/* HOSTOUTAGESORT structure */
|
||||||
|
typedef struct hostoutagesort_struct {
|
||||||
|
hostoutage *outage;
|
||||||
|
struct hostoutagesort_struct *next;
|
||||||
|
} hostoutagesort;
|
||||||
|
|
||||||
|
|
||||||
|
void document_header(int);
|
||||||
|
void document_footer(void);
|
||||||
|
int process_cgivars(void);
|
||||||
|
|
||||||
|
void display_network_outages(void);
|
||||||
|
void find_hosts_causing_outages(void);
|
||||||
|
void calculate_outage_effects(void);
|
||||||
|
void calculate_outage_effect_of_host(host *, int *, int *);
|
||||||
|
int is_route_to_host_blocked(host *);
|
||||||
|
int number_of_host_services(host *);
|
||||||
|
void add_hostoutage(host *);
|
||||||
|
void sort_hostoutages(void);
|
||||||
|
void free_hostoutage_list(void);
|
||||||
|
void free_hostoutagesort_list(void);
|
||||||
|
|
||||||
|
|
||||||
|
authdata current_authdata;
|
||||||
|
|
||||||
|
hostoutage *hostoutage_list = NULL;
|
||||||
|
hostoutagesort *hostoutagesort_list = NULL;
|
||||||
|
|
||||||
|
int service_severity_divisor = 4; /* default = services are 1/4 as important as hosts */
|
||||||
|
|
||||||
|
int embedded = FALSE;
|
||||||
|
int display_header = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
|
||||||
|
/* get the arguments passed in the URL */
|
||||||
|
process_cgivars();
|
||||||
|
|
||||||
|
/* reset internal variables */
|
||||||
|
reset_cgi_vars();
|
||||||
|
|
||||||
|
/* read the CGI configuration file */
|
||||||
|
result = read_cgi_config_file(get_cgi_config_location());
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
cgi_config_file_error(get_cgi_config_location());
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the main configuration file */
|
||||||
|
result = read_main_config_file(main_config_file);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
main_config_file_error(main_config_file);
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read all object configuration data */
|
||||||
|
result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
object_data_error();
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read all status data */
|
||||||
|
result = read_all_status_data(get_cgi_config_location(), READ_ALL_STATUS_DATA);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
status_data_error();
|
||||||
|
document_footer();
|
||||||
|
free_memory();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
document_header(TRUE);
|
||||||
|
|
||||||
|
/* get authentication information */
|
||||||
|
get_authentication_information(¤t_authdata);
|
||||||
|
|
||||||
|
if(display_header == TRUE) {
|
||||||
|
|
||||||
|
/* begin top table */
|
||||||
|
printf("<table border=0 width=100%%>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
|
||||||
|
/* left column of the first row */
|
||||||
|
printf("<td align=left valign=top width=33%%>\n");
|
||||||
|
display_info_table("Network Outages", TRUE, ¤t_authdata);
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* middle column of top row */
|
||||||
|
printf("<td align=center valign=top width=33%%>\n");
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* right column of top row */
|
||||||
|
printf("<td align=right valign=bottom width=33%%>\n");
|
||||||
|
|
||||||
|
/* display context-sensitive help */
|
||||||
|
display_context_help(CONTEXTHELP_OUTAGES);
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* end of top table */
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("</table>\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* display network outage info */
|
||||||
|
display_network_outages();
|
||||||
|
|
||||||
|
document_footer();
|
||||||
|
|
||||||
|
/* free memory allocated to comment data */
|
||||||
|
free_comment_data();
|
||||||
|
|
||||||
|
/* free all allocated memory */
|
||||||
|
free_memory();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void document_header(int use_stylesheet) {
|
||||||
|
char date_time[MAX_DATETIME_LENGTH];
|
||||||
|
time_t current_time;
|
||||||
|
time_t expire_time;
|
||||||
|
|
||||||
|
printf("Cache-Control: no-store\r\n");
|
||||||
|
printf("Pragma: no-cache\r\n");
|
||||||
|
printf("Refresh: %d\r\n", refresh_rate);
|
||||||
|
|
||||||
|
time(¤t_time);
|
||||||
|
get_time_string(¤t_time, date_time, (int)sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Last-Modified: %s\r\n", date_time);
|
||||||
|
|
||||||
|
expire_time = (time_t)0L;
|
||||||
|
get_time_string(&expire_time, date_time, (int)sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Expires: %s\r\n", date_time);
|
||||||
|
|
||||||
|
printf("Content-type: text/html\r\n\r\n");
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("<html>\n");
|
||||||
|
printf("<head>\n");
|
||||||
|
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
|
||||||
|
printf("<title>\n");
|
||||||
|
printf("Network Outages\n");
|
||||||
|
printf("</title>\n");
|
||||||
|
|
||||||
|
if(use_stylesheet == TRUE) {
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>", url_stylesheets_path, COMMON_CSS);
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>", url_stylesheets_path, OUTAGES_CSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</head>\n");
|
||||||
|
|
||||||
|
printf("<body CLASS='outages'>\n");
|
||||||
|
|
||||||
|
/* include user SSI header */
|
||||||
|
include_ssi_files(OUTAGES_CGI, SSI_HEADER);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void document_footer(void) {
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* include user SSI footer */
|
||||||
|
include_ssi_files(OUTAGES_CGI, SSI_FOOTER);
|
||||||
|
|
||||||
|
printf("</body>\n");
|
||||||
|
printf("</html>\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int process_cgivars(void) {
|
||||||
|
char **variables;
|
||||||
|
int error = FALSE;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
variables = getcgivars();
|
||||||
|
|
||||||
|
for(x = 0; variables[x] != NULL; x++) {
|
||||||
|
|
||||||
|
/* do some basic length checking on the variable identifier to prevent buffer overflows */
|
||||||
|
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
|
||||||
|
x++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the service severity divisor option */
|
||||||
|
if(!strcmp(variables[x], "service_divisor")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
service_severity_divisor = atoi(variables[x]);
|
||||||
|
if(service_severity_divisor < 1)
|
||||||
|
service_severity_divisor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the embed option */
|
||||||
|
else if(!strcmp(variables[x], "embedded"))
|
||||||
|
embedded = TRUE;
|
||||||
|
|
||||||
|
/* we found the noheader option */
|
||||||
|
else if(!strcmp(variables[x], "noheader"))
|
||||||
|
display_header = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory allocated to the CGI variables */
|
||||||
|
free_cgivars(variables);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* shows all hosts that are causing network outages */
|
||||||
|
void display_network_outages(void) {
|
||||||
|
char temp_buffer[MAX_INPUT_BUFFER];
|
||||||
|
int number_of_problem_hosts = 0;
|
||||||
|
int number_of_blocking_problem_hosts = 0;
|
||||||
|
hostoutagesort *temp_hostoutagesort;
|
||||||
|
hostoutage *temp_hostoutage;
|
||||||
|
hoststatus *temp_hoststatus;
|
||||||
|
int odd = 0;
|
||||||
|
char *bg_class = "";
|
||||||
|
char *status = "";
|
||||||
|
int days;
|
||||||
|
int hours;
|
||||||
|
int minutes;
|
||||||
|
int seconds;
|
||||||
|
int total_comments;
|
||||||
|
time_t t;
|
||||||
|
time_t current_time;
|
||||||
|
char state_duration[48];
|
||||||
|
int total_entries = 0;
|
||||||
|
|
||||||
|
/* user must be authorized for all hosts.. */
|
||||||
|
if(is_authorized_for_all_hosts(¤t_authdata) == FALSE) {
|
||||||
|
|
||||||
|
printf("<P><DIV CLASS='errorMessage'>It appears as though you do not have permission to view information you requested...</DIV></P>\n");
|
||||||
|
printf("<P><DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>");
|
||||||
|
printf("and check the authorization options in your CGI configuration file.</DIV></P>\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find all hosts that are causing network outages */
|
||||||
|
find_hosts_causing_outages();
|
||||||
|
|
||||||
|
/* calculate outage effects */
|
||||||
|
calculate_outage_effects();
|
||||||
|
|
||||||
|
/* sort the outage list by severity */
|
||||||
|
sort_hostoutages();
|
||||||
|
|
||||||
|
/* count the number of top-level hosts that are down and the ones that are actually blocking children hosts */
|
||||||
|
for(temp_hostoutage = hostoutage_list; temp_hostoutage != NULL; temp_hostoutage = temp_hostoutage->next) {
|
||||||
|
number_of_problem_hosts++;
|
||||||
|
if(temp_hostoutage->affected_child_hosts > 1)
|
||||||
|
number_of_blocking_problem_hosts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* display the problem hosts... */
|
||||||
|
printf("<P><DIV ALIGN=CENTER>\n");
|
||||||
|
printf("<DIV CLASS='dataTitle'>Blocking Outages</DIV>\n");
|
||||||
|
|
||||||
|
printf("<TABLE BORDER=0 CLASS='data'>\n");
|
||||||
|
printf("<TR>\n");
|
||||||
|
printf("<TH CLASS='data'>Severity</TH><TH CLASS='data'>Host</TH><TH CLASS='data'>State</TH><TH CLASS='data'>Notes</TH><TH CLASS='data'>State Duration</TH><TH CLASS='data'># Hosts Affected</TH><TH CLASS='data'># Services Affected</TH><TH CLASS='data'>Actions</TH>\n");
|
||||||
|
printf("</TR>\n");
|
||||||
|
|
||||||
|
for(temp_hostoutagesort = hostoutagesort_list; temp_hostoutagesort != NULL; temp_hostoutagesort = temp_hostoutagesort->next) {
|
||||||
|
|
||||||
|
temp_hostoutage = temp_hostoutagesort->outage;
|
||||||
|
if(temp_hostoutage == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* skip hosts that are not blocking anyone */
|
||||||
|
if(temp_hostoutage->affected_child_hosts <= 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
temp_hoststatus = find_hoststatus(temp_hostoutage->hst->name);
|
||||||
|
if(temp_hoststatus == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* make sure we only caught valid state types */
|
||||||
|
if(temp_hoststatus->status != HOST_DOWN && temp_hoststatus->status != HOST_UNREACHABLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
total_entries++;
|
||||||
|
|
||||||
|
if(odd == 0) {
|
||||||
|
odd = 1;
|
||||||
|
bg_class = "dataOdd";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
odd = 0;
|
||||||
|
bg_class = "dataEven";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(temp_hoststatus->status == HOST_UNREACHABLE)
|
||||||
|
status = "UNREACHABLE";
|
||||||
|
else if(temp_hoststatus->status == HOST_DOWN)
|
||||||
|
status = "DOWN";
|
||||||
|
|
||||||
|
printf("<TR CLASS='%s'>\n", bg_class);
|
||||||
|
|
||||||
|
printf("<TD CLASS='%s'>%d</TD>\n", bg_class, temp_hostoutage->severity);
|
||||||
|
printf("<TD CLASS='%s'><A HREF='%s?type=%d&host=%s'>%s</A></TD>\n", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_hostoutage->hst->name), temp_hostoutage->hst->name);
|
||||||
|
printf("<TD CLASS='host%s'>%s</TD>\n", status, status);
|
||||||
|
|
||||||
|
total_comments = number_of_host_comments(temp_hostoutage->hst->name);
|
||||||
|
if(total_comments > 0) {
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "This host has %d comment%s associated with it", total_comments, (total_comments == 1) ? "" : "s");
|
||||||
|
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
|
||||||
|
printf("<TD CLASS='%s'><A HREF='%s?type=%d&host=%s#comments'><IMG SRC='%s%s' BORDER=0 ALT='%s' TITLE='%s'></A></TD>\n", bg_class, EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(temp_hostoutage->hst->name), url_images_path, COMMENT_ICON, temp_buffer, temp_buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("<TD CLASS='%s'>N/A</TD>\n", bg_class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
current_time = time(NULL);
|
||||||
|
if(temp_hoststatus->last_state_change == (time_t)0)
|
||||||
|
t = current_time - program_start;
|
||||||
|
else
|
||||||
|
t = current_time - temp_hoststatus->last_state_change;
|
||||||
|
get_time_breakdown((unsigned long)t, &days, &hours, &minutes, &seconds);
|
||||||
|
snprintf(state_duration, sizeof(state_duration) - 1, "%2dd %2dh %2dm %2ds%s", days, hours, minutes, seconds, (temp_hoststatus->last_state_change == (time_t)0) ? "+" : "");
|
||||||
|
state_duration[sizeof(state_duration) - 1] = '\x0';
|
||||||
|
printf("<TD CLASS='%s'>%s</TD>\n", bg_class, state_duration);
|
||||||
|
|
||||||
|
printf("<TD CLASS='%s'>%d</TD>\n", bg_class, temp_hostoutage->affected_child_hosts);
|
||||||
|
printf("<TD CLASS='%s'>%d</TD>\n", bg_class, temp_hostoutage->affected_child_services);
|
||||||
|
|
||||||
|
printf("<TD CLASS='%s'>", bg_class);
|
||||||
|
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View status detail for this host' TITLE='View status detail for this host'></A>\n", STATUS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUS_DETAIL_ICON);
|
||||||
|
#ifdef USE_STATUSMAP
|
||||||
|
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View status map for this host and its children' TITLE='View status map for this host and its children'></A>\n", STATUSMAP_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUSMAP_ICON);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_STATUSWRL
|
||||||
|
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View 3-D status map for this host and its children' TITLE='View 3-D status map for this host and its children'></A>\n", STATUSWORLD_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, STATUSWORLD_ICON);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TRENDS
|
||||||
|
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View trends for this host' TITLE='View trends for this host'></A>\n", TRENDS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, TRENDS_ICON);
|
||||||
|
#endif
|
||||||
|
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View alert history for this host' TITLE='View alert history for this host'></A>\n", HISTORY_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, HISTORY_ICON);
|
||||||
|
printf("<A HREF='%s?host=%s'><IMG SRC='%s%s' BORDER=0 ALT='View notifications for this host' TITLE='View notifications for this host'></A>\n", NOTIFICATIONS_CGI, url_encode(temp_hostoutage->hst->name), url_images_path, NOTIFICATION_ICON);
|
||||||
|
printf("</TD>\n");
|
||||||
|
|
||||||
|
printf("</TR>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</TABLE>\n");
|
||||||
|
|
||||||
|
printf("</DIV></P>\n");
|
||||||
|
|
||||||
|
if(total_entries == 0)
|
||||||
|
printf("<DIV CLASS='itemTotalsTitle'>%d Blocking Outages Displayed</DIV>\n", total_entries);
|
||||||
|
|
||||||
|
/* free memory allocated to the host outage list */
|
||||||
|
free_hostoutage_list();
|
||||||
|
free_hostoutagesort_list();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* determine what hosts are causing network outages */
|
||||||
|
void find_hosts_causing_outages(void) {
|
||||||
|
hoststatus *temp_hoststatus;
|
||||||
|
host *temp_host;
|
||||||
|
|
||||||
|
/* check all hosts */
|
||||||
|
for(temp_hoststatus = hoststatus_list; temp_hoststatus != NULL; temp_hoststatus = temp_hoststatus->next) {
|
||||||
|
|
||||||
|
/* check only hosts that are not up and not pending */
|
||||||
|
if(temp_hoststatus->status != HOST_UP && temp_hoststatus->status != HOST_PENDING) {
|
||||||
|
|
||||||
|
/* find the host entry */
|
||||||
|
temp_host = find_host(temp_hoststatus->host_name);
|
||||||
|
|
||||||
|
if(temp_host == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* if the route to this host is not blocked, it is a causing an outage */
|
||||||
|
if(is_route_to_host_blocked(temp_host) == FALSE)
|
||||||
|
add_hostoutage(temp_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a host outage entry */
|
||||||
|
void add_hostoutage(host *hst) {
|
||||||
|
hostoutage *new_hostoutage;
|
||||||
|
|
||||||
|
/* allocate memory for a new structure */
|
||||||
|
new_hostoutage = (hostoutage *)malloc(sizeof(hostoutage));
|
||||||
|
|
||||||
|
if(new_hostoutage == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
new_hostoutage->hst = hst;
|
||||||
|
new_hostoutage->severity = 0;
|
||||||
|
new_hostoutage->affected_child_hosts = 0;
|
||||||
|
new_hostoutage->affected_child_services = 0;
|
||||||
|
|
||||||
|
/* add the structure to the head of the list in memory */
|
||||||
|
new_hostoutage->next = hostoutage_list;
|
||||||
|
hostoutage_list = new_hostoutage;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* frees all memory allocated to the host outage list */
|
||||||
|
void free_hostoutage_list(void) {
|
||||||
|
hostoutage *this_hostoutage;
|
||||||
|
hostoutage *next_hostoutage;
|
||||||
|
|
||||||
|
/* free all list members */
|
||||||
|
for(this_hostoutage = hostoutage_list; this_hostoutage != NULL; this_hostoutage = next_hostoutage) {
|
||||||
|
next_hostoutage = this_hostoutage->next;
|
||||||
|
free(this_hostoutage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset list pointer */
|
||||||
|
hostoutage_list = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* frees all memory allocated to the host outage sort list */
|
||||||
|
void free_hostoutagesort_list(void) {
|
||||||
|
hostoutagesort *this_hostoutagesort;
|
||||||
|
hostoutagesort *next_hostoutagesort;
|
||||||
|
|
||||||
|
/* free all list members */
|
||||||
|
for(this_hostoutagesort = hostoutagesort_list; this_hostoutagesort != NULL; this_hostoutagesort = next_hostoutagesort) {
|
||||||
|
next_hostoutagesort = this_hostoutagesort->next;
|
||||||
|
free(this_hostoutagesort);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset list pointer */
|
||||||
|
hostoutagesort_list = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* calculates network outage effect of all hosts that are causing blockages */
|
||||||
|
void calculate_outage_effects(void) {
|
||||||
|
hostoutage *temp_hostoutage;
|
||||||
|
|
||||||
|
/* check all hosts causing problems */
|
||||||
|
for(temp_hostoutage = hostoutage_list; temp_hostoutage != NULL; temp_hostoutage = temp_hostoutage->next) {
|
||||||
|
|
||||||
|
/* calculate the outage effect of this particular hosts */
|
||||||
|
calculate_outage_effect_of_host(temp_hostoutage->hst, &temp_hostoutage->affected_child_hosts, &temp_hostoutage->affected_child_services);
|
||||||
|
|
||||||
|
temp_hostoutage->severity = (temp_hostoutage->affected_child_hosts + (temp_hostoutage->affected_child_services / service_severity_divisor));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* calculates network outage effect of a particular host being down or unreachable */
|
||||||
|
void calculate_outage_effect_of_host(host *hst, int *affected_hosts, int *affected_services) {
|
||||||
|
int total_child_hosts_affected = 0;
|
||||||
|
int total_child_services_affected = 0;
|
||||||
|
int temp_child_hosts_affected = 0;
|
||||||
|
int temp_child_services_affected = 0;
|
||||||
|
host *temp_host;
|
||||||
|
|
||||||
|
|
||||||
|
/* find all child hosts of this host */
|
||||||
|
for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {
|
||||||
|
|
||||||
|
/* skip this host if it is not a child */
|
||||||
|
if(is_host_immediate_child_of_host(hst, temp_host) == FALSE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* calculate the outage effect of the child */
|
||||||
|
calculate_outage_effect_of_host(temp_host, &temp_child_hosts_affected, &temp_child_services_affected);
|
||||||
|
|
||||||
|
/* keep a running total of outage effects */
|
||||||
|
total_child_hosts_affected += temp_child_hosts_affected;
|
||||||
|
total_child_services_affected += temp_child_services_affected;
|
||||||
|
}
|
||||||
|
|
||||||
|
*affected_hosts = total_child_hosts_affected + 1;
|
||||||
|
*affected_services = total_child_services_affected + number_of_host_services(hst);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* tests whether or not a host is "blocked" by upstream parents (host is already assumed to be down or unreachable) */
|
||||||
|
int is_route_to_host_blocked(host *hst) {
|
||||||
|
hostsmember *temp_hostsmember;
|
||||||
|
hoststatus *temp_hoststatus;
|
||||||
|
|
||||||
|
/* if the host has no parents, it is not being blocked by anyone */
|
||||||
|
if(hst->parent_hosts == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* check all parent hosts */
|
||||||
|
for(temp_hostsmember = hst->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
|
||||||
|
|
||||||
|
/* find the parent host's status */
|
||||||
|
temp_hoststatus = find_hoststatus(temp_hostsmember->host_name);
|
||||||
|
|
||||||
|
if(temp_hoststatus == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* at least one parent it up (or pending), so this host is not blocked */
|
||||||
|
if(temp_hoststatus->status == HOST_UP || temp_hoststatus->status == HOST_PENDING)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* calculates the number of services associated a particular host */
|
||||||
|
int number_of_host_services(host *hst) {
|
||||||
|
int total_services = 0;
|
||||||
|
service *temp_service;
|
||||||
|
|
||||||
|
/* check all services */
|
||||||
|
for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
|
||||||
|
|
||||||
|
if(!strcmp(temp_service->host_name, hst->name))
|
||||||
|
total_services++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_services;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* sort the host outages by severity */
|
||||||
|
void sort_hostoutages(void) {
|
||||||
|
hostoutagesort *last_hostoutagesort;
|
||||||
|
hostoutagesort *new_hostoutagesort;
|
||||||
|
hostoutagesort *temp_hostoutagesort;
|
||||||
|
hostoutage *temp_hostoutage;
|
||||||
|
|
||||||
|
if(hostoutage_list == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* sort all host outage entries */
|
||||||
|
for(temp_hostoutage = hostoutage_list; temp_hostoutage != NULL; temp_hostoutage = temp_hostoutage->next) {
|
||||||
|
|
||||||
|
/* allocate memory for a new sort structure */
|
||||||
|
new_hostoutagesort = (hostoutagesort *)malloc(sizeof(hostoutagesort));
|
||||||
|
if(new_hostoutagesort == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
new_hostoutagesort->outage = temp_hostoutage;
|
||||||
|
|
||||||
|
last_hostoutagesort = hostoutagesort_list;
|
||||||
|
for(temp_hostoutagesort = hostoutagesort_list; temp_hostoutagesort != NULL; temp_hostoutagesort = temp_hostoutagesort->next) {
|
||||||
|
|
||||||
|
if(new_hostoutagesort->outage->severity >= temp_hostoutagesort->outage->severity) {
|
||||||
|
new_hostoutagesort->next = temp_hostoutagesort;
|
||||||
|
if(temp_hostoutagesort == hostoutagesort_list)
|
||||||
|
hostoutagesort_list = new_hostoutagesort;
|
||||||
|
else
|
||||||
|
last_hostoutagesort->next = new_hostoutagesort;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
last_hostoutagesort = temp_hostoutagesort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hostoutagesort_list == NULL) {
|
||||||
|
new_hostoutagesort->next = NULL;
|
||||||
|
hostoutagesort_list = new_hostoutagesort;
|
||||||
|
}
|
||||||
|
else if(temp_hostoutagesort == NULL) {
|
||||||
|
new_hostoutagesort->next = NULL;
|
||||||
|
last_hostoutagesort->next = new_hostoutagesort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
550
cgi/showlog.c
Normal file
@ -0,0 +1,550 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* SHOWLOG.C - Nagios Log File CGI
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 01-08-2008
|
||||||
|
*
|
||||||
|
* This CGI program will display the contents of the Nagios
|
||||||
|
* log 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.
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
|
||||||
|
#include "../include/getcgi.h"
|
||||||
|
#include "../include/cgiutils.h"
|
||||||
|
#include "../include/cgiauth.h"
|
||||||
|
|
||||||
|
extern char main_config_file[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_html_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_images_path[MAX_FILENAME_LENGTH];
|
||||||
|
extern char url_stylesheets_path[MAX_FILENAME_LENGTH];
|
||||||
|
|
||||||
|
extern int log_rotation_method;
|
||||||
|
|
||||||
|
extern int enable_splunk_integration;
|
||||||
|
|
||||||
|
void document_header(int);
|
||||||
|
void document_footer(void);
|
||||||
|
int process_cgivars(void);
|
||||||
|
|
||||||
|
authdata current_authdata;
|
||||||
|
|
||||||
|
int display_log(void);
|
||||||
|
|
||||||
|
char log_file_to_use[MAX_FILENAME_LENGTH] = "";
|
||||||
|
int log_archive = 0;
|
||||||
|
|
||||||
|
int use_lifo = TRUE;
|
||||||
|
|
||||||
|
int embedded = FALSE;
|
||||||
|
int display_header = TRUE;
|
||||||
|
int display_frills = TRUE;
|
||||||
|
int display_timebreaks = TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int result = OK;
|
||||||
|
char temp_buffer[MAX_INPUT_BUFFER];
|
||||||
|
|
||||||
|
|
||||||
|
/* get the CGI variables passed in the URL */
|
||||||
|
process_cgivars();
|
||||||
|
|
||||||
|
/* reset internal variables */
|
||||||
|
reset_cgi_vars();
|
||||||
|
|
||||||
|
/* read the CGI configuration file */
|
||||||
|
result = read_cgi_config_file(get_cgi_config_location());
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
cgi_config_file_error(get_cgi_config_location());
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the main configuration file */
|
||||||
|
result = read_main_config_file(main_config_file);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
main_config_file_error(main_config_file);
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read all object configuration data */
|
||||||
|
result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA);
|
||||||
|
if(result == ERROR) {
|
||||||
|
document_header(FALSE);
|
||||||
|
object_data_error();
|
||||||
|
document_footer();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document_header(TRUE);
|
||||||
|
|
||||||
|
/* get authentication information */
|
||||||
|
get_authentication_information(¤t_authdata);
|
||||||
|
|
||||||
|
/* determine what log file we should be using */
|
||||||
|
get_log_archive_to_use(log_archive, log_file_to_use, (int)sizeof(log_file_to_use));
|
||||||
|
|
||||||
|
if(display_header == TRUE) {
|
||||||
|
|
||||||
|
/* begin top table */
|
||||||
|
printf("<table border=0 width=100%% cellpadding=0 cellspacing=0>\n");
|
||||||
|
printf("<tr>\n");
|
||||||
|
|
||||||
|
/* left column of top table - info box */
|
||||||
|
printf("<td align=left valign=top width=33%%>\n");
|
||||||
|
display_info_table((log_rotation_method == LOG_ROTATION_NONE || log_archive == 0) ? "Current Event Log" : "Archived Event Log", FALSE, ¤t_authdata);
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* middle column of top table - log file navigation options */
|
||||||
|
printf("<td align=center valign=top width=33%%>\n");
|
||||||
|
snprintf(temp_buffer, sizeof(temp_buffer) - 1, "%s?%s", SHOWLOG_CGI, (use_lifo == FALSE) ? "oldestfirst&" : "");
|
||||||
|
temp_buffer[sizeof(temp_buffer) - 1] = '\x0';
|
||||||
|
display_nav_table(temp_buffer, log_archive);
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* right hand column of top row */
|
||||||
|
printf("<td align=right valign=top width=33%%>\n");
|
||||||
|
|
||||||
|
printf("<form method='GET' action='%s'>\n", SHOWLOG_CGI);
|
||||||
|
printf("<input type='hidden' name='archive' value='%d'>\n", log_archive);
|
||||||
|
printf("<table border=0 cellspacing=0 cellpadding=0 CLASS='optBox'>\n");
|
||||||
|
printf("<tr>");
|
||||||
|
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='checkbox' name='oldestfirst' %s> Older Entries First:</td>", (use_lifo == FALSE) ? "checked" : "");
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("<tr>");
|
||||||
|
printf("<td align=left valign=bottom CLASS='optBoxItem'><input type='submit' value='Update'></td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
/* display context-sensitive help */
|
||||||
|
printf("<tr>\n");
|
||||||
|
printf("<td align=right>\n");
|
||||||
|
display_context_help(CONTEXTHELP_LOG);
|
||||||
|
printf("</td>\n");
|
||||||
|
printf("</tr>\n");
|
||||||
|
|
||||||
|
printf("</table>\n");
|
||||||
|
printf("</form>\n");
|
||||||
|
|
||||||
|
printf("</td>\n");
|
||||||
|
|
||||||
|
/* end of top table */
|
||||||
|
printf("</tr>\n");
|
||||||
|
printf("</table>\n");
|
||||||
|
printf("</p>\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* display the contents of the log file */
|
||||||
|
display_log();
|
||||||
|
|
||||||
|
document_footer();
|
||||||
|
|
||||||
|
/* free allocated memory */
|
||||||
|
free_memory();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void document_header(int use_stylesheet) {
|
||||||
|
char date_time[MAX_DATETIME_LENGTH];
|
||||||
|
time_t current_time;
|
||||||
|
time_t expire_time;
|
||||||
|
|
||||||
|
printf("Cache-Control: no-store\r\n");
|
||||||
|
printf("Pragma: no-cache\r\n");
|
||||||
|
|
||||||
|
time(¤t_time);
|
||||||
|
get_time_string(¤t_time, date_time, (int)sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Last-Modified: %s\r\n", date_time);
|
||||||
|
|
||||||
|
expire_time = (time_t)0L;
|
||||||
|
get_time_string(&expire_time, date_time, (int)sizeof(date_time), HTTP_DATE_TIME);
|
||||||
|
printf("Expires: %s\r\n", date_time);
|
||||||
|
|
||||||
|
printf("Content-type: text/html\r\n\r\n");
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("<HTML>\n");
|
||||||
|
printf("<HEAD>\n");
|
||||||
|
printf("<link rel=\"shortcut icon\" href=\"%sfavicon.ico\" type=\"image/ico\">\n", url_images_path);
|
||||||
|
printf("<TITLE>\n");
|
||||||
|
printf("Nagios Log File\n");
|
||||||
|
printf("</TITLE>\n");
|
||||||
|
|
||||||
|
if(use_stylesheet == TRUE) {
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, COMMON_CSS);
|
||||||
|
printf("<LINK REL='stylesheet' TYPE='text/css' HREF='%s%s'>\n", url_stylesheets_path, SHOWLOG_CSS);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</HEAD>\n");
|
||||||
|
printf("<BODY CLASS='showlog'>\n");
|
||||||
|
|
||||||
|
/* include user SSI header */
|
||||||
|
include_ssi_files(SHOWLOG_CGI, SSI_HEADER);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void document_footer(void) {
|
||||||
|
|
||||||
|
if(embedded == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* include user SSI footer */
|
||||||
|
include_ssi_files(SHOWLOG_CGI, SSI_FOOTER);
|
||||||
|
|
||||||
|
printf("</BODY>\n");
|
||||||
|
printf("</HTML>\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int process_cgivars(void) {
|
||||||
|
char **variables;
|
||||||
|
int error = FALSE;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
variables = getcgivars();
|
||||||
|
|
||||||
|
for(x = 0; variables[x] != NULL; x++) {
|
||||||
|
|
||||||
|
/* do some basic length checking on the variable identifier to prevent buffer overflows */
|
||||||
|
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the archive argument */
|
||||||
|
else if(!strcmp(variables[x], "archive")) {
|
||||||
|
x++;
|
||||||
|
if(variables[x] == NULL) {
|
||||||
|
error = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_archive = atoi(variables[x]);
|
||||||
|
if(log_archive < 0)
|
||||||
|
log_archive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the order argument */
|
||||||
|
else if(!strcmp(variables[x], "oldestfirst")) {
|
||||||
|
use_lifo = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found the embed option */
|
||||||
|
else if(!strcmp(variables[x], "embedded"))
|
||||||
|
embedded = TRUE;
|
||||||
|
|
||||||
|
/* we found the noheader option */
|
||||||
|
else if(!strcmp(variables[x], "noheader"))
|
||||||
|
display_header = FALSE;
|
||||||
|
|
||||||
|
/* we found the nofrills option */
|
||||||
|
else if(!strcmp(variables[x], "nofrills"))
|
||||||
|
display_frills = FALSE;
|
||||||
|
|
||||||
|
/* we found the notimebreaks option */
|
||||||
|
else if(!strcmp(variables[x], "notimebreaks"))
|
||||||
|
display_timebreaks = FALSE;
|
||||||
|
|
||||||
|
/* we received an invalid argument */
|
||||||
|
else
|
||||||
|
error = TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory allocated to the CGI variables */
|
||||||
|
free_cgivars(variables);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* display the contents of the log file */
|
||||||
|
int display_log(void) {
|
||||||
|
char *input = NULL;
|
||||||
|
char image[MAX_INPUT_BUFFER];
|
||||||
|
char image_alt[MAX_INPUT_BUFFER];
|
||||||
|
time_t t;
|
||||||
|
char *temp_buffer = NULL;
|
||||||
|
char date_time[MAX_DATETIME_LENGTH];
|
||||||
|
int error = FALSE;
|
||||||
|
mmapfile *thefile = NULL;
|
||||||
|
char last_message_date[MAX_INPUT_BUFFER] = "";
|
||||||
|
char current_message_date[MAX_INPUT_BUFFER] = "";
|
||||||
|
struct tm *time_ptr = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* check to see if the user is authorized to view the log file */
|
||||||
|
if(is_authorized_for_system_information(¤t_authdata) == FALSE) {
|
||||||
|
printf("<HR>\n");
|
||||||
|
printf("<DIV CLASS='errorMessage'>It appears as though you do not have permission to view the log file...</DIV><br><br>\n");
|
||||||
|
printf("<DIV CLASS='errorDescription'>If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI<br>and check the authorization options in your CGI configuration file.</DIV>\n");
|
||||||
|
printf("<HR>\n");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = FALSE;
|
||||||
|
|
||||||
|
if(use_lifo == TRUE) {
|
||||||
|
error = read_file_into_lifo(log_file_to_use);
|
||||||
|
if(error != LIFO_OK) {
|
||||||
|
if(error == LIFO_ERROR_MEMORY) {
|
||||||
|
printf("<P><DIV CLASS='warningMessage'>Not enough memory to reverse log file - displaying log in natural order...</DIV></P>");
|
||||||
|
error = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = TRUE;
|
||||||
|
use_lifo = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_lifo == FALSE) {
|
||||||
|
|
||||||
|
if((thefile = mmap_fopen(log_file_to_use)) == NULL) {
|
||||||
|
printf("<HR>\n");
|
||||||
|
printf("<P><DIV CLASS='errorMessage'>Error: Could not open log file '%s' for reading!</DIV></P>", log_file_to_use);
|
||||||
|
printf("<HR>\n");
|
||||||
|
error = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(error == FALSE) {
|
||||||
|
|
||||||
|
printf("<P><DIV CLASS='logEntries'>\n");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
free(input);
|
||||||
|
|
||||||
|
if(use_lifo == TRUE) {
|
||||||
|
if((input = pop_lifo()) == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if((input = mmap_fgets(thefile)) == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
strip(input);
|
||||||
|
|
||||||
|
if(strstr(input, " starting...")) {
|
||||||
|
strcpy(image, START_ICON);
|
||||||
|
strcpy(image_alt, START_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, " shutting down...")) {
|
||||||
|
strcpy(image, STOP_ICON);
|
||||||
|
strcpy(image_alt, STOP_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "Bailing out")) {
|
||||||
|
strcpy(image, STOP_ICON);
|
||||||
|
strcpy(image_alt, STOP_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, " restarting...")) {
|
||||||
|
strcpy(image, RESTART_ICON);
|
||||||
|
strcpy(image_alt, RESTART_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST ALERT:") && strstr(input, ";DOWN;")) {
|
||||||
|
strcpy(image, HOST_DOWN_ICON);
|
||||||
|
strcpy(image_alt, HOST_DOWN_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST ALERT:") && strstr(input, ";UNREACHABLE;")) {
|
||||||
|
strcpy(image, HOST_UNREACHABLE_ICON);
|
||||||
|
strcpy(image_alt, HOST_UNREACHABLE_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST ALERT:") && (strstr(input, ";RECOVERY;") || strstr(input, ";UP;"))) {
|
||||||
|
strcpy(image, HOST_UP_ICON);
|
||||||
|
strcpy(image_alt, HOST_UP_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST NOTIFICATION:")) {
|
||||||
|
strcpy(image, HOST_NOTIFICATION_ICON);
|
||||||
|
strcpy(image_alt, HOST_NOTIFICATION_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE ALERT:") && strstr(input, ";CRITICAL;")) {
|
||||||
|
strcpy(image, CRITICAL_ICON);
|
||||||
|
strcpy(image_alt, CRITICAL_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE ALERT:") && strstr(input, ";WARNING;")) {
|
||||||
|
strcpy(image, WARNING_ICON);
|
||||||
|
strcpy(image_alt, WARNING_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE ALERT:") && strstr(input, ";UNKNOWN;")) {
|
||||||
|
strcpy(image, UNKNOWN_ICON);
|
||||||
|
strcpy(image_alt, UNKNOWN_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE ALERT:") && (strstr(input, ";RECOVERY;") || strstr(input, ";OK;"))) {
|
||||||
|
strcpy(image, OK_ICON);
|
||||||
|
strcpy(image_alt, OK_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE NOTIFICATION:")) {
|
||||||
|
strcpy(image, NOTIFICATION_ICON);
|
||||||
|
strcpy(image_alt, NOTIFICATION_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE EVENT HANDLER:")) {
|
||||||
|
strcpy(image, SERVICE_EVENT_ICON);
|
||||||
|
strcpy(image_alt, SERVICE_EVENT_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST EVENT HANDLER:")) {
|
||||||
|
strcpy(image, HOST_EVENT_ICON);
|
||||||
|
strcpy(image_alt, HOST_EVENT_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "EXTERNAL COMMAND:")) {
|
||||||
|
strcpy(image, EXTERNAL_COMMAND_ICON);
|
||||||
|
strcpy(image_alt, EXTERNAL_COMMAND_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "PASSIVE SERVICE CHECK:")) {
|
||||||
|
strcpy(image, PASSIVE_ICON);
|
||||||
|
strcpy(image_alt, "Passive Service Check");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "PASSIVE HOST CHECK:")) {
|
||||||
|
strcpy(image, PASSIVE_ICON);
|
||||||
|
strcpy(image_alt, "Passive Host Check");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "LOG ROTATION:")) {
|
||||||
|
strcpy(image, LOG_ROTATION_ICON);
|
||||||
|
strcpy(image_alt, LOG_ROTATION_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "active mode...")) {
|
||||||
|
strcpy(image, ACTIVE_ICON);
|
||||||
|
strcpy(image_alt, ACTIVE_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "standby mode...")) {
|
||||||
|
strcpy(image, STANDBY_ICON);
|
||||||
|
strcpy(image_alt, STANDBY_ICON_ALT);
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE FLAPPING ALERT:") && strstr(input, ";STARTED;")) {
|
||||||
|
strcpy(image, FLAPPING_ICON);
|
||||||
|
strcpy(image_alt, "Service started flapping");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE FLAPPING ALERT:") && strstr(input, ";STOPPED;")) {
|
||||||
|
strcpy(image, FLAPPING_ICON);
|
||||||
|
strcpy(image_alt, "Service stopped flapping");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE FLAPPING ALERT:") && strstr(input, ";DISABLED;")) {
|
||||||
|
strcpy(image, FLAPPING_ICON);
|
||||||
|
strcpy(image_alt, "Service flap detection disabled");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST FLAPPING ALERT:") && strstr(input, ";STARTED;")) {
|
||||||
|
strcpy(image, FLAPPING_ICON);
|
||||||
|
strcpy(image_alt, "Host started flapping");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST FLAPPING ALERT:") && strstr(input, ";STOPPED;")) {
|
||||||
|
strcpy(image, FLAPPING_ICON);
|
||||||
|
strcpy(image_alt, "Host stopped flapping");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST FLAPPING ALERT:") && strstr(input, ";DISABLED;")) {
|
||||||
|
strcpy(image, FLAPPING_ICON);
|
||||||
|
strcpy(image_alt, "Host flap detection disabled");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE DOWNTIME ALERT:") && strstr(input, ";STARTED;")) {
|
||||||
|
strcpy(image, SCHEDULED_DOWNTIME_ICON);
|
||||||
|
strcpy(image_alt, "Service entered a period of scheduled downtime");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE DOWNTIME ALERT:") && strstr(input, ";STOPPED;")) {
|
||||||
|
strcpy(image, SCHEDULED_DOWNTIME_ICON);
|
||||||
|
strcpy(image_alt, "Service exited a period of scheduled downtime");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "SERVICE DOWNTIME ALERT:") && strstr(input, ";CANCELLED;")) {
|
||||||
|
strcpy(image, SCHEDULED_DOWNTIME_ICON);
|
||||||
|
strcpy(image_alt, "Service scheduled downtime has been cancelled");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST DOWNTIME ALERT:") && strstr(input, ";STARTED;")) {
|
||||||
|
strcpy(image, SCHEDULED_DOWNTIME_ICON);
|
||||||
|
strcpy(image_alt, "Host entered a period of scheduled downtime");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST DOWNTIME ALERT:") && strstr(input, ";STOPPED;")) {
|
||||||
|
strcpy(image, SCHEDULED_DOWNTIME_ICON);
|
||||||
|
strcpy(image_alt, "Host exited a period of scheduled downtime");
|
||||||
|
}
|
||||||
|
else if(strstr(input, "HOST DOWNTIME ALERT:") && strstr(input, ";CANCELLED;")) {
|
||||||
|
strcpy(image, SCHEDULED_DOWNTIME_ICON);
|
||||||
|
strcpy(image_alt, "Host scheduled downtime has been cancelled");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strcpy(image, INFO_ICON);
|
||||||
|
strcpy(image_alt, INFO_ICON_ALT);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_buffer = strtok(input, "]");
|
||||||
|
t = (temp_buffer == NULL) ? 0L : strtoul(temp_buffer + 1, NULL, 10);
|
||||||
|
|
||||||
|
time_ptr = localtime(&t);
|
||||||
|
strftime(current_message_date, sizeof(current_message_date), "%B %d, %Y %H:00\n", time_ptr);
|
||||||
|
current_message_date[sizeof(current_message_date) - 1] = '\x0';
|
||||||
|
|
||||||
|
if(strcmp(last_message_date, current_message_date) != 0 && display_timebreaks == TRUE) {
|
||||||
|
printf("<BR CLEAR='all'>\n");
|
||||||
|
printf("<DIV CLASS='dateTimeBreak'>\n");
|
||||||
|
printf("<table border=0 width=95%%><tr>");
|
||||||
|
printf("<td width=40%%><hr width=100%%></td>");
|
||||||
|
printf("<td align=center CLASS='dateTimeBreak'>%s</td>", current_message_date);
|
||||||
|
printf("<td width=40%%><hr width=100%%></td>");
|
||||||
|
printf("</tr></table>\n");
|
||||||
|
printf("</DIV>\n");
|
||||||
|
printf("<BR CLEAR='all'><DIV CLASS='logEntries'>\n");
|
||||||
|
strncpy(last_message_date, current_message_date, sizeof(last_message_date));
|
||||||
|
last_message_date[sizeof(last_message_date) - 1] = '\x0';
|
||||||
|
}
|
||||||
|
|
||||||
|
get_time_string(&t, date_time, (int)sizeof(date_time), SHORT_DATE_TIME);
|
||||||
|
strip(date_time);
|
||||||
|
|
||||||
|
temp_buffer = strtok(NULL, "\n");
|
||||||
|
|
||||||
|
if(display_frills == TRUE)
|
||||||
|
printf("<img align='left' src='%s%s' alt='%s' title='%s'>", url_images_path, image, image_alt, image_alt);
|
||||||
|
printf("[%s] %s", date_time, (temp_buffer == NULL) ? "" : html_encode(temp_buffer, FALSE));
|
||||||
|
if(enable_splunk_integration == TRUE) {
|
||||||
|
printf(" ");
|
||||||
|
display_splunk_generic_url(temp_buffer, 2);
|
||||||
|
}
|
||||||
|
printf("<br clear='all'>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("</DIV></P>\n");
|
||||||
|
printf("<HR>\n");
|
||||||
|
|
||||||
|
free(input);
|
||||||
|
|
||||||
|
if(use_lifo == FALSE)
|
||||||
|
mmap_fclose(thefile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(use_lifo == TRUE)
|
||||||
|
free_lifo_memory();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
5469
cgi/status.c
Normal file
2859
cgi/statusmap.c
Normal file
1515
cgi/statuswml.c
Normal file
1301
cgi/statuswrl.c
Normal file
2808
cgi/summary.c
Normal file
3052
cgi/trends.c
Normal file
1
common/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Makefile
|
39
common/Makefile.in
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
############################
|
||||||
|
# Makefile for Nagios
|
||||||
|
#
|
||||||
|
# Last Modified: 04-08-2003
|
||||||
|
############################
|
||||||
|
|
||||||
|
# Source code directories
|
||||||
|
SRC_BASE=../common
|
||||||
|
SRC_CGI=../cgi
|
||||||
|
|
||||||
|
CC=@CC@
|
||||||
|
CFLAGS=@CFLAGS@ @DEFS@
|
||||||
|
LDFLAGS=@LDFLAGS@ @LIBS@
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
LOGDIR=@localstatedir@
|
||||||
|
CFGDIR=@sysconfdir@
|
||||||
|
BINDIR=@bindir@
|
||||||
|
CGIDIR=@sbindir@
|
||||||
|
HTMLDIR=@datarootdir@
|
||||||
|
INSTALL=@INSTALL@
|
||||||
|
INSTALL_OPTS=@INSTALL_OPTS@
|
||||||
|
COMMAND_OPTS=@COMMAND_OPTS@
|
||||||
|
|
||||||
|
CP=@CP@
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f core *.o
|
||||||
|
rm -f *~
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile
|
||||||
|
|
||||||
|
devclean: distclean
|
||||||
|
|
||||||
|
install:
|
||||||
|
|
742
common/comments.c
Normal file
@ -0,0 +1,742 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* COMMENTS.C - Comment functions for Nagios
|
||||||
|
*
|
||||||
|
* Copyright (c) 1999-2010 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 08-28-2010
|
||||||
|
*
|
||||||
|
* 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 "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/comments.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
|
||||||
|
/***** IMPLEMENTATION-SPECIFIC INCLUDES *****/
|
||||||
|
|
||||||
|
#ifdef USE_XCDDEFAULT
|
||||||
|
#include "../xdata/xcddefault.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NSCORE
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
#include "../include/broker.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NSCGI
|
||||||
|
#include "../include/cgiutils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
comment *comment_list = NULL;
|
||||||
|
int defer_comment_sorting = 0;
|
||||||
|
comment **comment_hashlist = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NSCORE
|
||||||
|
pthread_mutex_t nagios_comment_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/**************** INITIALIZATION/CLEANUP FUNCTIONS ****************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* initializes comment data */
|
||||||
|
int initialize_comment_data(char *config_file) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XCDDEFAULT
|
||||||
|
result = xcddefault_initialize_comment_data(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* removes old/invalid comments */
|
||||||
|
int cleanup_comment_data(char *config_file) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XCDDEFAULT
|
||||||
|
result = xcddefault_cleanup_comment_data(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/****************** COMMENT OUTPUT FUNCTIONS **********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a new host or service comment */
|
||||||
|
int add_new_comment(int type, int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id) {
|
||||||
|
int result = OK;
|
||||||
|
unsigned long new_comment_id = 0L;
|
||||||
|
|
||||||
|
if(type == HOST_COMMENT)
|
||||||
|
result = add_new_host_comment(entry_type, host_name, entry_time, author_name, comment_data, persistent, source, expires, expire_time, &new_comment_id);
|
||||||
|
else
|
||||||
|
result = add_new_service_comment(entry_type, host_name, svc_description, entry_time, author_name, comment_data, persistent, source, expires, expire_time, &new_comment_id);
|
||||||
|
|
||||||
|
/* add an event to expire comment data if necessary... */
|
||||||
|
if(expires == TRUE)
|
||||||
|
schedule_new_event(EVENT_EXPIRE_COMMENT, FALSE, expire_time, FALSE, 0, NULL, TRUE, (void *)new_comment_id, NULL, 0);
|
||||||
|
|
||||||
|
/* save comment id */
|
||||||
|
if(comment_id != NULL)
|
||||||
|
*comment_id = new_comment_id;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a new host comment */
|
||||||
|
int add_new_host_comment(int entry_type, char *host_name, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id) {
|
||||||
|
int result = OK;
|
||||||
|
unsigned long new_comment_id = 0L;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XCDDEFAULT
|
||||||
|
result = xcddefault_add_new_host_comment(entry_type, host_name, entry_time, author_name, comment_data, persistent, source, expires, expire_time, &new_comment_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* save comment id */
|
||||||
|
if(comment_id != NULL)
|
||||||
|
*comment_id = new_comment_id;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_comment_data(NEBTYPE_COMMENT_ADD, NEBFLAG_NONE, NEBATTR_NONE, HOST_COMMENT, entry_type, host_name, NULL, entry_time, author_name, comment_data, persistent, source, expires, expire_time, new_comment_id, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a new service comment */
|
||||||
|
int add_new_service_comment(int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author_name, char *comment_data, int persistent, int source, int expires, time_t expire_time, unsigned long *comment_id) {
|
||||||
|
int result = OK;
|
||||||
|
unsigned long new_comment_id = 0L;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XCDDEFAULT
|
||||||
|
result = xcddefault_add_new_service_comment(entry_type, host_name, svc_description, entry_time, author_name, comment_data, persistent, source, expires, expire_time, &new_comment_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* save comment id */
|
||||||
|
if(comment_id != NULL)
|
||||||
|
*comment_id = new_comment_id;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_comment_data(NEBTYPE_COMMENT_ADD, NEBFLAG_NONE, NEBATTR_NONE, SERVICE_COMMENT, entry_type, host_name, svc_description, entry_time, author_name, comment_data, persistent, source, expires, expire_time, new_comment_id, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/***************** COMMENT DELETION FUNCTIONS *********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes a host or service comment */
|
||||||
|
int delete_comment(int type, unsigned long comment_id) {
|
||||||
|
int result = OK;
|
||||||
|
comment *this_comment = NULL;
|
||||||
|
comment *last_comment = NULL;
|
||||||
|
comment *next_comment = NULL;
|
||||||
|
int hashslot = 0;
|
||||||
|
comment *this_hash = NULL;
|
||||||
|
comment *last_hash = NULL;
|
||||||
|
|
||||||
|
/* lock the comments so we can modify them safely */
|
||||||
|
#ifdef NSCORE
|
||||||
|
pthread_mutex_lock(&nagios_comment_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* find the comment we should remove */
|
||||||
|
for(this_comment = comment_list, last_comment = comment_list; this_comment != NULL; this_comment = next_comment) {
|
||||||
|
next_comment = this_comment->next;
|
||||||
|
|
||||||
|
/* we found the comment we should delete */
|
||||||
|
if(this_comment->comment_id == comment_id && this_comment->comment_type == type)
|
||||||
|
break;
|
||||||
|
|
||||||
|
last_comment = this_comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove the comment from the list in memory */
|
||||||
|
if(this_comment != NULL) {
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_comment_data(NEBTYPE_COMMENT_DELETE, NEBFLAG_NONE, NEBATTR_NONE, type, this_comment->entry_type, this_comment->host_name, this_comment->service_description, this_comment->entry_time, this_comment->author, this_comment->comment_data, this_comment->persistent, this_comment->source, this_comment->expires, this_comment->expire_time, comment_id, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* first remove from chained hash list */
|
||||||
|
hashslot = hashfunc(this_comment->host_name, NULL, COMMENT_HASHSLOTS);
|
||||||
|
last_hash = NULL;
|
||||||
|
for(this_hash = comment_hashlist[hashslot]; this_hash; this_hash = this_hash->nexthash) {
|
||||||
|
if(this_hash == this_comment) {
|
||||||
|
if(last_hash)
|
||||||
|
last_hash->nexthash = this_hash->nexthash;
|
||||||
|
else {
|
||||||
|
if(this_hash->nexthash)
|
||||||
|
comment_hashlist[hashslot] = this_hash->nexthash;
|
||||||
|
else
|
||||||
|
comment_hashlist[hashslot] = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last_hash = this_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* then removed from linked list */
|
||||||
|
if(comment_list == this_comment)
|
||||||
|
comment_list = this_comment->next;
|
||||||
|
else
|
||||||
|
last_comment->next = next_comment;
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(this_comment->host_name);
|
||||||
|
my_free(this_comment->service_description);
|
||||||
|
my_free(this_comment->author);
|
||||||
|
my_free(this_comment->comment_data);
|
||||||
|
my_free(this_comment);
|
||||||
|
|
||||||
|
result = OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = ERROR;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XCDDEFAULT
|
||||||
|
if(type == HOST_COMMENT)
|
||||||
|
result = xcddefault_delete_host_comment(comment_id);
|
||||||
|
else
|
||||||
|
result = xcddefault_delete_service_comment(comment_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NSCORE
|
||||||
|
pthread_mutex_unlock(&nagios_comment_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes a host comment */
|
||||||
|
int delete_host_comment(unsigned long comment_id) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/* delete the comment from memory */
|
||||||
|
result = delete_comment(HOST_COMMENT, comment_id);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes a service comment */
|
||||||
|
int delete_service_comment(unsigned long comment_id) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/* delete the comment from memory */
|
||||||
|
result = delete_comment(SERVICE_COMMENT, comment_id);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes all comments for a particular host or service */
|
||||||
|
int delete_all_comments(int type, char *host_name, char *svc_description) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
if(type == HOST_COMMENT)
|
||||||
|
result = delete_all_host_comments(host_name);
|
||||||
|
else
|
||||||
|
result = delete_all_service_comments(host_name, svc_description);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes all comments for a particular host */
|
||||||
|
int delete_all_host_comments(char *host_name) {
|
||||||
|
int result = OK;
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
comment *next_comment = NULL;
|
||||||
|
|
||||||
|
if(host_name == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* delete host comments from memory */
|
||||||
|
for(temp_comment = get_first_comment_by_host(host_name); temp_comment != NULL; temp_comment = next_comment) {
|
||||||
|
next_comment = get_next_comment_by_host(host_name, temp_comment);
|
||||||
|
if(temp_comment->comment_type == HOST_COMMENT)
|
||||||
|
delete_comment(HOST_COMMENT, temp_comment->comment_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes all non-persistent acknowledgement comments for a particular host */
|
||||||
|
int delete_host_acknowledgement_comments(host *hst) {
|
||||||
|
int result = OK;
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
comment *next_comment = NULL;
|
||||||
|
|
||||||
|
if(hst == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* delete comments from memory */
|
||||||
|
temp_comment = get_first_comment_by_host(hst->name);
|
||||||
|
while(temp_comment) {
|
||||||
|
next_comment = get_next_comment_by_host(hst->name, temp_comment);
|
||||||
|
if(temp_comment->comment_type == HOST_COMMENT && temp_comment->entry_type == ACKNOWLEDGEMENT_COMMENT && temp_comment->persistent == FALSE) {
|
||||||
|
delete_comment(HOST_COMMENT, temp_comment->comment_id);
|
||||||
|
}
|
||||||
|
temp_comment = next_comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes all comments for a particular service */
|
||||||
|
int delete_all_service_comments(char *host_name, char *svc_description) {
|
||||||
|
int result = OK;
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
comment *next_comment = NULL;
|
||||||
|
|
||||||
|
if(host_name == NULL || svc_description == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* delete service comments from memory */
|
||||||
|
for(temp_comment = comment_list; temp_comment != NULL; temp_comment = next_comment) {
|
||||||
|
next_comment = temp_comment->next;
|
||||||
|
if(temp_comment->comment_type == SERVICE_COMMENT && !strcmp(temp_comment->host_name, host_name) && !strcmp(temp_comment->service_description, svc_description))
|
||||||
|
delete_comment(SERVICE_COMMENT, temp_comment->comment_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deletes all non-persistent acknowledgement comments for a particular service */
|
||||||
|
int delete_service_acknowledgement_comments(service *svc) {
|
||||||
|
int result = OK;
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
comment *next_comment = NULL;
|
||||||
|
|
||||||
|
if(svc == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* delete comments from memory */
|
||||||
|
for(temp_comment = comment_list; temp_comment != NULL; temp_comment = next_comment) {
|
||||||
|
next_comment = temp_comment->next;
|
||||||
|
if(temp_comment->comment_type == SERVICE_COMMENT && !strcmp(temp_comment->host_name, svc->host_name) && !strcmp(temp_comment->service_description, svc->description) && temp_comment->entry_type == ACKNOWLEDGEMENT_COMMENT && temp_comment->persistent == FALSE)
|
||||||
|
delete_comment(SERVICE_COMMENT, temp_comment->comment_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* checks for an expired comment (and removes it) */
|
||||||
|
int check_for_expired_comment(unsigned long comment_id) {
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
|
||||||
|
/* check all comments */
|
||||||
|
for(temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) {
|
||||||
|
|
||||||
|
/* delete the now expired comment */
|
||||||
|
if(temp_comment->comment_id == comment_id && temp_comment->expires == TRUE && temp_comment->expire_time < time(NULL)) {
|
||||||
|
delete_comment(temp_comment->comment_type, comment_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/****************** CHAINED HASH FUNCTIONS ************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* adds comment to hash list in memory */
|
||||||
|
int add_comment_to_hashlist(comment *new_comment) {
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
comment *lastpointer = NULL;
|
||||||
|
int hashslot = 0;
|
||||||
|
|
||||||
|
/* initialize hash list */
|
||||||
|
if(comment_hashlist == NULL) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
comment_hashlist = (comment **)malloc(sizeof(comment *) * COMMENT_HASHSLOTS);
|
||||||
|
if(comment_hashlist == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(i = 0; i < COMMENT_HASHSLOTS; i++)
|
||||||
|
comment_hashlist[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!new_comment)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
hashslot = hashfunc(new_comment->host_name, NULL, COMMENT_HASHSLOTS);
|
||||||
|
lastpointer = NULL;
|
||||||
|
for(temp_comment = comment_hashlist[hashslot]; temp_comment && compare_hashdata(temp_comment->host_name, NULL, new_comment->host_name, NULL) < 0; temp_comment = temp_comment->nexthash) {
|
||||||
|
if(compare_hashdata(temp_comment->host_name, NULL, new_comment->host_name, NULL) >= 0)
|
||||||
|
break;
|
||||||
|
lastpointer = temp_comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* multiples are allowed */
|
||||||
|
if(lastpointer)
|
||||||
|
lastpointer->nexthash = new_comment;
|
||||||
|
else
|
||||||
|
comment_hashlist[hashslot] = new_comment;
|
||||||
|
new_comment->nexthash = temp_comment;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/******************** ADDITION FUNCTIONS **************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a host comment to the list in memory */
|
||||||
|
int add_host_comment(int entry_type, char *host_name, time_t entry_time, char *author, char *comment_data, unsigned long comment_id, int persistent, int expires, time_t expire_time, int source) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
result = add_comment(HOST_COMMENT, entry_type, host_name, NULL, entry_time, author, comment_data, comment_id, persistent, expires, expire_time, source);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a service comment to the list in memory */
|
||||||
|
int add_service_comment(int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, unsigned long comment_id, int persistent, int expires, time_t expire_time, int source) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
result = add_comment(SERVICE_COMMENT, entry_type, host_name, svc_description, entry_time, author, comment_data, comment_id, persistent, expires, expire_time, source);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a comment to the list in memory */
|
||||||
|
int add_comment(int comment_type, int entry_type, char *host_name, char *svc_description, time_t entry_time, char *author, char *comment_data, unsigned long comment_id, int persistent, int expires, time_t expire_time, int source) {
|
||||||
|
comment *new_comment = NULL;
|
||||||
|
comment *last_comment = NULL;
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/* make sure we have the data we need */
|
||||||
|
if(host_name == NULL || author == NULL || comment_data == NULL || (comment_type == SERVICE_COMMENT && svc_description == NULL))
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* allocate memory for the comment */
|
||||||
|
if((new_comment = (comment *)calloc(1, sizeof(comment))) == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* duplicate vars */
|
||||||
|
if((new_comment->host_name = (char *)strdup(host_name)) == NULL)
|
||||||
|
result = ERROR;
|
||||||
|
if(comment_type == SERVICE_COMMENT) {
|
||||||
|
if((new_comment->service_description = (char *)strdup(svc_description)) == NULL)
|
||||||
|
result = ERROR;
|
||||||
|
}
|
||||||
|
if((new_comment->author = (char *)strdup(author)) == NULL)
|
||||||
|
result = ERROR;
|
||||||
|
if((new_comment->comment_data = (char *)strdup(comment_data)) == NULL)
|
||||||
|
result = ERROR;
|
||||||
|
|
||||||
|
new_comment->comment_type = comment_type;
|
||||||
|
new_comment->entry_type = entry_type;
|
||||||
|
new_comment->source = source;
|
||||||
|
new_comment->entry_time = entry_time;
|
||||||
|
new_comment->comment_id = comment_id;
|
||||||
|
new_comment->persistent = (persistent == TRUE) ? TRUE : FALSE;
|
||||||
|
new_comment->expires = (expires == TRUE) ? TRUE : FALSE;
|
||||||
|
new_comment->expire_time = expire_time;
|
||||||
|
|
||||||
|
/* add comment to hash list */
|
||||||
|
if(result == OK) {
|
||||||
|
if(!add_comment_to_hashlist(new_comment))
|
||||||
|
result = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle errors */
|
||||||
|
if(result == ERROR) {
|
||||||
|
my_free(new_comment->comment_data);
|
||||||
|
my_free(new_comment->author);
|
||||||
|
my_free(new_comment->service_description);
|
||||||
|
my_free(new_comment->host_name);
|
||||||
|
my_free(new_comment);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(defer_comment_sorting) {
|
||||||
|
new_comment->next = comment_list;
|
||||||
|
comment_list = new_comment;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* add new comment to comment list, sorted by comment id,
|
||||||
|
* but lock the list first so broker threads doesn't crash
|
||||||
|
* out in case they're modifying this list too
|
||||||
|
*/
|
||||||
|
#ifdef NSCORE
|
||||||
|
pthread_mutex_lock(&nagios_comment_lock);
|
||||||
|
#endif
|
||||||
|
last_comment = comment_list;
|
||||||
|
for(temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) {
|
||||||
|
if(new_comment->comment_id < temp_comment->comment_id) {
|
||||||
|
new_comment->next = temp_comment;
|
||||||
|
if(temp_comment == comment_list)
|
||||||
|
comment_list = new_comment;
|
||||||
|
else
|
||||||
|
last_comment->next = new_comment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
last_comment = temp_comment;
|
||||||
|
}
|
||||||
|
if(comment_list == NULL) {
|
||||||
|
new_comment->next = NULL;
|
||||||
|
comment_list = new_comment;
|
||||||
|
}
|
||||||
|
else if(temp_comment == NULL) {
|
||||||
|
new_comment->next = NULL;
|
||||||
|
last_comment->next = new_comment;
|
||||||
|
}
|
||||||
|
#ifdef NSCORE
|
||||||
|
pthread_mutex_unlock(&nagios_comment_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NSCORE
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_comment_data(NEBTYPE_COMMENT_LOAD, NEBFLAG_NONE, NEBATTR_NONE, comment_type, entry_type, host_name, svc_description, entry_time, author, comment_data, persistent, source, expires, expire_time, comment_id, NULL);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int comment_compar(const void *p1, const void *p2) {
|
||||||
|
comment *c1 = *(comment **)p1;
|
||||||
|
comment *c2 = *(comment **)p2;
|
||||||
|
return (c1->comment_id < c2->comment_id) ? -1 : (c1->comment_id - c2->comment_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sort_comments(void) {
|
||||||
|
comment **array, *temp_comment;
|
||||||
|
unsigned long i = 0, unsorted_comments = 0;
|
||||||
|
|
||||||
|
if(!defer_comment_sorting)
|
||||||
|
return OK;
|
||||||
|
defer_comment_sorting = 0;
|
||||||
|
|
||||||
|
temp_comment = comment_list;
|
||||||
|
while(temp_comment != NULL) {
|
||||||
|
temp_comment = temp_comment->next;
|
||||||
|
unsorted_comments++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!unsorted_comments)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
if(!(array = malloc(sizeof(*array) * unsorted_comments)))
|
||||||
|
return ERROR;
|
||||||
|
while(comment_list) {
|
||||||
|
array[i++] = comment_list;
|
||||||
|
comment_list = comment_list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort((void *)array, i, sizeof(*array), comment_compar);
|
||||||
|
comment_list = temp_comment = array[0];
|
||||||
|
for(i = 1; i < unsorted_comments; i++) {
|
||||||
|
temp_comment->next = array[i];
|
||||||
|
temp_comment = temp_comment->next;
|
||||||
|
}
|
||||||
|
temp_comment->next = NULL;
|
||||||
|
my_free(array);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/********************* CLEANUP FUNCTIONS **************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* frees memory allocated for the comment data */
|
||||||
|
void free_comment_data(void) {
|
||||||
|
comment *this_comment = NULL;
|
||||||
|
comment *next_comment = NULL;
|
||||||
|
|
||||||
|
/* free memory for the comment list */
|
||||||
|
for(this_comment = comment_list; this_comment != NULL; this_comment = next_comment) {
|
||||||
|
next_comment = this_comment->next;
|
||||||
|
my_free(this_comment->host_name);
|
||||||
|
my_free(this_comment->service_description);
|
||||||
|
my_free(this_comment->author);
|
||||||
|
my_free(this_comment->comment_data);
|
||||||
|
my_free(this_comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free hash list and reset list pointer */
|
||||||
|
my_free(comment_hashlist);
|
||||||
|
comment_hashlist = NULL;
|
||||||
|
comment_list = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/********************* UTILITY FUNCTIONS **************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* get the number of comments associated with a particular host */
|
||||||
|
int number_of_host_comments(char *host_name) {
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
int total_comments = 0;
|
||||||
|
|
||||||
|
if(host_name == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(temp_comment = get_first_comment_by_host(host_name); temp_comment != NULL; temp_comment = get_next_comment_by_host(host_name, temp_comment)) {
|
||||||
|
if(temp_comment->comment_type == HOST_COMMENT)
|
||||||
|
total_comments++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get the number of comments associated with a particular service */
|
||||||
|
int number_of_service_comments(char *host_name, char *svc_description) {
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
int total_comments = 0;
|
||||||
|
|
||||||
|
if(host_name == NULL || svc_description == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(temp_comment = get_first_comment_by_host(host_name); temp_comment != NULL; temp_comment = get_next_comment_by_host(host_name, temp_comment)) {
|
||||||
|
if(temp_comment->comment_type == SERVICE_COMMENT && !strcmp(temp_comment->service_description, svc_description))
|
||||||
|
total_comments++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total_comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/********************* TRAVERSAL FUNCTIONS ************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
comment *get_first_comment_by_host(char *host_name) {
|
||||||
|
|
||||||
|
return get_next_comment_by_host(host_name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
comment *get_next_comment_by_host(char *host_name, comment *start) {
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
|
||||||
|
if(host_name == NULL || comment_hashlist == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(start == NULL)
|
||||||
|
temp_comment = comment_hashlist[hashfunc(host_name, NULL, COMMENT_HASHSLOTS)];
|
||||||
|
else
|
||||||
|
temp_comment = start->nexthash;
|
||||||
|
|
||||||
|
for(; temp_comment && compare_hashdata(temp_comment->host_name, NULL, host_name, NULL) < 0; temp_comment = temp_comment->nexthash);
|
||||||
|
|
||||||
|
if(temp_comment && compare_hashdata(temp_comment->host_name, NULL, host_name, NULL) == 0)
|
||||||
|
return temp_comment;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/********************** SEARCH FUNCTIONS **************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* find a service comment by id */
|
||||||
|
comment *find_service_comment(unsigned long comment_id) {
|
||||||
|
|
||||||
|
return find_comment(comment_id, SERVICE_COMMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* find a host comment by id */
|
||||||
|
comment *find_host_comment(unsigned long comment_id) {
|
||||||
|
|
||||||
|
return find_comment(comment_id, HOST_COMMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* find a comment by id */
|
||||||
|
comment *find_comment(unsigned long comment_id, int comment_type) {
|
||||||
|
comment *temp_comment = NULL;
|
||||||
|
|
||||||
|
for(temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) {
|
||||||
|
if(temp_comment->comment_id == comment_id && temp_comment->comment_type == comment_type)
|
||||||
|
return temp_comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
1260
common/downtime.c
Normal file
3356
common/macros.c
Normal file
3613
common/objects.c
Normal file
511
common/shared.c
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file holds random utility functions shared by cgi's and
|
||||||
|
* core.
|
||||||
|
*/
|
||||||
|
extern int date_format;
|
||||||
|
|
||||||
|
/* fix the problem with strtok() skipping empty options between tokens */
|
||||||
|
char *my_strtok(char *buffer, char *tokens) {
|
||||||
|
char *token_position = NULL;
|
||||||
|
char *sequence_head = NULL;
|
||||||
|
static char *my_strtok_buffer = NULL;
|
||||||
|
static char *original_my_strtok_buffer = NULL;
|
||||||
|
|
||||||
|
if(buffer != NULL) {
|
||||||
|
my_free(original_my_strtok_buffer);
|
||||||
|
if((my_strtok_buffer = (char *)strdup(buffer)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
original_my_strtok_buffer = my_strtok_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
sequence_head = my_strtok_buffer;
|
||||||
|
|
||||||
|
if(sequence_head[0] == '\x0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
token_position = strchr(my_strtok_buffer, tokens[0]);
|
||||||
|
|
||||||
|
if(token_position == NULL) {
|
||||||
|
my_strtok_buffer = strchr(my_strtok_buffer, '\x0');
|
||||||
|
return sequence_head;
|
||||||
|
}
|
||||||
|
|
||||||
|
token_position[0] = '\x0';
|
||||||
|
my_strtok_buffer = token_position + 1;
|
||||||
|
|
||||||
|
return sequence_head;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fixes compiler problems under Solaris, since strsep() isn't included */
|
||||||
|
/* this code is taken from the glibc source */
|
||||||
|
char *my_strsep(char **stringp, const char *delim) {
|
||||||
|
char *begin, *end;
|
||||||
|
|
||||||
|
begin = *stringp;
|
||||||
|
if(begin == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* A frequent case is when the delimiter string contains only one
|
||||||
|
* character. Here we don't need to call the expensive `strpbrk'
|
||||||
|
* function and instead work using `strchr'. */
|
||||||
|
if(delim[0] == '\0' || delim[1] == '\0') {
|
||||||
|
char ch = delim[0];
|
||||||
|
|
||||||
|
if(ch == '\0' || begin[0] == '\0')
|
||||||
|
end = NULL;
|
||||||
|
else {
|
||||||
|
if(*begin == ch)
|
||||||
|
end = begin;
|
||||||
|
else
|
||||||
|
end = strchr(begin + 1, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* find the end of the token. */
|
||||||
|
end = strpbrk(begin, delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(end) {
|
||||||
|
/* terminate the token and set *STRINGP past NUL character. */
|
||||||
|
*end++ = '\0';
|
||||||
|
*stringp = end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* no more delimiters; this is the last token. */
|
||||||
|
*stringp = NULL;
|
||||||
|
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open a file read-only via mmap() */
|
||||||
|
mmapfile *mmap_fopen(char *filename) {
|
||||||
|
mmapfile *new_mmapfile = NULL;
|
||||||
|
int fd = 0;
|
||||||
|
void *mmap_buf = NULL;
|
||||||
|
struct stat statbuf;
|
||||||
|
int mode = O_RDONLY;
|
||||||
|
unsigned long file_size = 0L;
|
||||||
|
|
||||||
|
if(filename == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* allocate memory */
|
||||||
|
if((new_mmapfile = (mmapfile *) malloc(sizeof(mmapfile))) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* open the file */
|
||||||
|
if((fd = open(filename, mode)) == -1) {
|
||||||
|
my_free(new_mmapfile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get file info */
|
||||||
|
if((fstat(fd, &statbuf)) == -1) {
|
||||||
|
close(fd);
|
||||||
|
my_free(new_mmapfile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get file size */
|
||||||
|
file_size = (unsigned long)statbuf.st_size;
|
||||||
|
|
||||||
|
/* only mmap() if we have a file greater than 0 bytes */
|
||||||
|
if(file_size > 0) {
|
||||||
|
|
||||||
|
/* mmap() the file - allocate one extra byte for processing zero-byte files */
|
||||||
|
if((mmap_buf =
|
||||||
|
(void *)mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd,
|
||||||
|
0)) == MAP_FAILED) {
|
||||||
|
close(fd);
|
||||||
|
my_free(new_mmapfile);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mmap_buf = NULL;
|
||||||
|
|
||||||
|
/* populate struct info for later use */
|
||||||
|
new_mmapfile->path = (char *)strdup(filename);
|
||||||
|
new_mmapfile->fd = fd;
|
||||||
|
new_mmapfile->file_size = (unsigned long)file_size;
|
||||||
|
new_mmapfile->current_position = 0L;
|
||||||
|
new_mmapfile->current_line = 0L;
|
||||||
|
new_mmapfile->mmap_buf = mmap_buf;
|
||||||
|
|
||||||
|
return new_mmapfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close a file originally opened via mmap() */
|
||||||
|
int mmap_fclose(mmapfile * temp_mmapfile) {
|
||||||
|
|
||||||
|
if(temp_mmapfile == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* un-mmap() the file */
|
||||||
|
if(temp_mmapfile->file_size > 0L)
|
||||||
|
munmap(temp_mmapfile->mmap_buf, temp_mmapfile->file_size);
|
||||||
|
|
||||||
|
/* close the file */
|
||||||
|
close(temp_mmapfile->fd);
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
my_free(temp_mmapfile->path);
|
||||||
|
my_free(temp_mmapfile);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gets one line of input from an mmap()'ed file */
|
||||||
|
char *mmap_fgets(mmapfile * temp_mmapfile) {
|
||||||
|
char *buf = NULL;
|
||||||
|
unsigned long x = 0L;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if(temp_mmapfile == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* size of file is 0 bytes */
|
||||||
|
if(temp_mmapfile->file_size == 0L)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* we've reached the end of the file */
|
||||||
|
if(temp_mmapfile->current_position >= temp_mmapfile->file_size)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* find the end of the string (or buffer) */
|
||||||
|
for(x = temp_mmapfile->current_position; x < temp_mmapfile->file_size;
|
||||||
|
x++) {
|
||||||
|
if(*((char *)(temp_mmapfile->mmap_buf) + x) == '\n') {
|
||||||
|
x++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate length of line we just read */
|
||||||
|
len = (int)(x - temp_mmapfile->current_position);
|
||||||
|
|
||||||
|
/* allocate memory for the new line */
|
||||||
|
if((buf = (char *)malloc(len + 1)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* copy string to newly allocated memory and terminate the string */
|
||||||
|
memcpy(buf,
|
||||||
|
((char *)(temp_mmapfile->mmap_buf) +
|
||||||
|
temp_mmapfile->current_position), len);
|
||||||
|
buf[len] = '\x0';
|
||||||
|
|
||||||
|
/* update the current position */
|
||||||
|
temp_mmapfile->current_position = x;
|
||||||
|
|
||||||
|
/* increment the current line */
|
||||||
|
temp_mmapfile->current_line++;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gets one line of input from an mmap()'ed file (may be contained on more than one line in the source file) */
|
||||||
|
char *mmap_fgets_multiline(mmapfile * temp_mmapfile) {
|
||||||
|
char *buf = NULL;
|
||||||
|
char *tempbuf = NULL;
|
||||||
|
char *stripped = NULL;
|
||||||
|
int len = 0;
|
||||||
|
int len2 = 0;
|
||||||
|
int end = 0;
|
||||||
|
|
||||||
|
if(temp_mmapfile == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
my_free(tempbuf);
|
||||||
|
|
||||||
|
if((tempbuf = mmap_fgets(temp_mmapfile)) == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(buf == NULL) {
|
||||||
|
len = strlen(tempbuf);
|
||||||
|
if((buf = (char *)malloc(len + 1)) == NULL)
|
||||||
|
break;
|
||||||
|
memcpy(buf, tempbuf, len);
|
||||||
|
buf[len] = '\x0';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* strip leading white space from continuation lines */
|
||||||
|
stripped = tempbuf;
|
||||||
|
while(*stripped == ' ' || *stripped == '\t')
|
||||||
|
stripped++;
|
||||||
|
len = strlen(stripped);
|
||||||
|
len2 = strlen(buf);
|
||||||
|
if((buf =
|
||||||
|
(char *)realloc(buf, len + len2 + 1)) == NULL)
|
||||||
|
break;
|
||||||
|
strcat(buf, stripped);
|
||||||
|
len += len2;
|
||||||
|
buf[len] = '\x0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* handle Windows/DOS CR/LF */
|
||||||
|
if(len >= 2 && buf[len - 2] == '\r')
|
||||||
|
end = len - 3;
|
||||||
|
/* normal Unix LF */
|
||||||
|
else if(len >= 1 && buf[len - 1] == '\n')
|
||||||
|
end = len - 2;
|
||||||
|
else
|
||||||
|
end = len - 1;
|
||||||
|
|
||||||
|
/* two backslashes found. unescape first backslash first and break */
|
||||||
|
if(end >= 1 && buf[end - 1] == '\\' && buf[end] == '\\') {
|
||||||
|
buf[end] = '\n';
|
||||||
|
buf[end + 1] = '\x0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* one backslash found. continue reading the next line */
|
||||||
|
else if(end > 0 && buf[end] == '\\')
|
||||||
|
buf[end] = '\x0';
|
||||||
|
|
||||||
|
/* no continuation marker was found, so break */
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_free(tempbuf);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strip newline, carriage return, and tab characters from beginning and end of a string */
|
||||||
|
void strip(char *buffer) {
|
||||||
|
register int x, z;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(buffer == NULL || buffer[0] == '\x0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* strip end of string */
|
||||||
|
len = (int)strlen(buffer);
|
||||||
|
for(x = len - 1; x >= 0; x--) {
|
||||||
|
switch(buffer[x]) {
|
||||||
|
case ' ':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case '\t':
|
||||||
|
buffer[x] = '\x0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we stripped all of it, just return */
|
||||||
|
if(!x)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* save last position for later... */
|
||||||
|
z = x;
|
||||||
|
|
||||||
|
/* strip beginning of string (by shifting) */
|
||||||
|
/* NOTE: this is very expensive to do, so avoid it whenever possible */
|
||||||
|
for(x = 0;; x++) {
|
||||||
|
switch(buffer[x]) {
|
||||||
|
case ' ':
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
case '\t':
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x > 0 && z > 0) {
|
||||||
|
/* new length of the string after we stripped the end */
|
||||||
|
len = z + 1;
|
||||||
|
|
||||||
|
/* shift chars towards beginning of string to remove leading whitespace */
|
||||||
|
for(z = x; z < len; z++)
|
||||||
|
buffer[z - x] = buffer[z];
|
||||||
|
buffer[len - x] = '\x0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
*************** HASH FUNCTIONS *******************
|
||||||
|
**************************************************/
|
||||||
|
/* dual hash function */
|
||||||
|
int hashfunc(const char *name1, const char *name2, int hashslots) {
|
||||||
|
unsigned int i, result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
if(name1)
|
||||||
|
for(i = 0; i < strlen(name1); i++)
|
||||||
|
result += name1[i];
|
||||||
|
|
||||||
|
if(name2)
|
||||||
|
for(i = 0; i < strlen(name2); i++)
|
||||||
|
result += name2[i];
|
||||||
|
|
||||||
|
result = result % hashslots;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dual hash data comparison */
|
||||||
|
int compare_hashdata(const char *val1a, const char *val1b, const char *val2a,
|
||||||
|
const char *val2b) {
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
/* NOTE: If hash calculation changes, update the compare_strings() function! */
|
||||||
|
|
||||||
|
/* check first name */
|
||||||
|
if(val1a == NULL && val2a == NULL)
|
||||||
|
result = 0;
|
||||||
|
else if(val1a == NULL)
|
||||||
|
result = 1;
|
||||||
|
else if(val2a == NULL)
|
||||||
|
result = -1;
|
||||||
|
else
|
||||||
|
result = strcmp(val1a, val2a);
|
||||||
|
|
||||||
|
/* check second name if necessary */
|
||||||
|
if(result == 0) {
|
||||||
|
if(val1b == NULL && val2b == NULL)
|
||||||
|
result = 0;
|
||||||
|
else if(val1b == NULL)
|
||||||
|
result = 1;
|
||||||
|
else if(val2b == NULL)
|
||||||
|
result = -1;
|
||||||
|
else
|
||||||
|
result = strcmp(val1b, val2b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* given a date/time in time_t format, produce a corresponding
|
||||||
|
* date/time string, including timezone
|
||||||
|
*/
|
||||||
|
void get_datetime_string(time_t * raw_time, char *buffer, int buffer_length,
|
||||||
|
int type) {
|
||||||
|
time_t t;
|
||||||
|
struct tm *tm_ptr, tm_s;
|
||||||
|
int hour;
|
||||||
|
int minute;
|
||||||
|
int second;
|
||||||
|
int month;
|
||||||
|
int day;
|
||||||
|
int year;
|
||||||
|
char *weekdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||||
|
char *months[12] = {
|
||||||
|
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept",
|
||||||
|
"Oct", "Nov", "Dec"
|
||||||
|
};
|
||||||
|
char *tzone = "";
|
||||||
|
|
||||||
|
if(raw_time == NULL)
|
||||||
|
time(&t);
|
||||||
|
else
|
||||||
|
t = *raw_time;
|
||||||
|
|
||||||
|
if(type == HTTP_DATE_TIME)
|
||||||
|
tm_ptr = gmtime_r(&t, &tm_s);
|
||||||
|
else
|
||||||
|
tm_ptr = localtime_r(&t, &tm_s);
|
||||||
|
|
||||||
|
hour = tm_ptr->tm_hour;
|
||||||
|
minute = tm_ptr->tm_min;
|
||||||
|
second = tm_ptr->tm_sec;
|
||||||
|
month = tm_ptr->tm_mon + 1;
|
||||||
|
day = tm_ptr->tm_mday;
|
||||||
|
year = tm_ptr->tm_year + 1900;
|
||||||
|
|
||||||
|
#ifdef HAVE_TM_ZONE
|
||||||
|
tzone = (char *)(tm_ptr->tm_zone);
|
||||||
|
#else
|
||||||
|
tzone = (tm_ptr->tm_isdst) ? tzname[1] : tzname[0];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ctime() style date/time */
|
||||||
|
if(type == LONG_DATE_TIME)
|
||||||
|
snprintf(buffer, buffer_length, "%s %s %d %02d:%02d:%02d %s %d",
|
||||||
|
weekdays[tm_ptr->tm_wday], months[tm_ptr->tm_mon], day,
|
||||||
|
hour, minute, second, tzone, year);
|
||||||
|
|
||||||
|
/* short date/time */
|
||||||
|
else if(type == SHORT_DATE_TIME) {
|
||||||
|
if(date_format == DATE_FORMAT_EURO)
|
||||||
|
snprintf(buffer, buffer_length,
|
||||||
|
"%02d-%02d-%04d %02d:%02d:%02d", day, month,
|
||||||
|
year, hour, minute, second);
|
||||||
|
else if(date_format == DATE_FORMAT_ISO8601
|
||||||
|
|| date_format == DATE_FORMAT_STRICT_ISO8601)
|
||||||
|
snprintf(buffer, buffer_length,
|
||||||
|
"%04d-%02d-%02d%c%02d:%02d:%02d", year, month,
|
||||||
|
day,
|
||||||
|
(date_format ==
|
||||||
|
DATE_FORMAT_STRICT_ISO8601) ? 'T' : ' ', hour,
|
||||||
|
minute, second);
|
||||||
|
else
|
||||||
|
snprintf(buffer, buffer_length,
|
||||||
|
"%02d-%02d-%04d %02d:%02d:%02d", month, day,
|
||||||
|
year, hour, minute, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* short date */
|
||||||
|
else if(type == SHORT_DATE) {
|
||||||
|
if(date_format == DATE_FORMAT_EURO)
|
||||||
|
snprintf(buffer, buffer_length, "%02d-%02d-%04d", day,
|
||||||
|
month, year);
|
||||||
|
else if(date_format == DATE_FORMAT_ISO8601
|
||||||
|
|| date_format == DATE_FORMAT_STRICT_ISO8601)
|
||||||
|
snprintf(buffer, buffer_length, "%04d-%02d-%02d", year,
|
||||||
|
month, day);
|
||||||
|
else
|
||||||
|
snprintf(buffer, buffer_length, "%02d-%02d-%04d", month,
|
||||||
|
day, year);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expiration date/time for HTTP headers */
|
||||||
|
else if(type == HTTP_DATE_TIME)
|
||||||
|
snprintf(buffer, buffer_length,
|
||||||
|
"%s, %02d %s %d %02d:%02d:%02d GMT",
|
||||||
|
weekdays[tm_ptr->tm_wday], day, months[tm_ptr->tm_mon],
|
||||||
|
year, hour, minute, second);
|
||||||
|
|
||||||
|
/* short time */
|
||||||
|
else
|
||||||
|
snprintf(buffer, buffer_length, "%02d:%02d:%02d", hour, minute,
|
||||||
|
second);
|
||||||
|
|
||||||
|
buffer[buffer_length - 1] = '\x0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get days, hours, minutes, and seconds from a raw time_t format or total seconds */
|
||||||
|
void get_time_breakdown(unsigned long raw_time, int *days, int *hours,
|
||||||
|
int *minutes, int *seconds) {
|
||||||
|
unsigned long temp_time;
|
||||||
|
int temp_days;
|
||||||
|
int temp_hours;
|
||||||
|
int temp_minutes;
|
||||||
|
int temp_seconds;
|
||||||
|
|
||||||
|
temp_time = raw_time;
|
||||||
|
|
||||||
|
temp_days = temp_time / 86400;
|
||||||
|
temp_time -= (temp_days * 86400);
|
||||||
|
temp_hours = temp_time / 3600;
|
||||||
|
temp_time -= (temp_hours * 3600);
|
||||||
|
temp_minutes = temp_time / 60;
|
||||||
|
temp_time -= (temp_minutes * 60);
|
||||||
|
temp_seconds = (int)temp_time;
|
||||||
|
|
||||||
|
*days = temp_days;
|
||||||
|
*hours = temp_hours;
|
||||||
|
*minutes = temp_minutes;
|
||||||
|
*seconds = temp_seconds;
|
||||||
|
}
|
558
common/skiplist.c
Normal file
@ -0,0 +1,558 @@
|
|||||||
|
/************************************************************************
|
||||||
|
*
|
||||||
|
* SKIPLIST.C - Skiplist functions for use in Nagios event/object lists
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 Ethan Galstad
|
||||||
|
* Last Modified: 02-28-2008
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* These function implement a slightly modified skiplist from that
|
||||||
|
* described by William Pugh (ftp://ftp.cs.umd.edu/pub/skipLists/skiplists.pdf).
|
||||||
|
* The structures and function were modified to allow the list to act
|
||||||
|
* like a priority queue for the Nagios event list/queue(s). Multiple nodes with
|
||||||
|
* the same key value are allowed on the list to accomodate multiple events
|
||||||
|
* occurring at the same (second) point in time. Implemented peek() and pop()
|
||||||
|
* functions to allow for quick event queue processing, and a method to delete
|
||||||
|
* a specific list item, based on its pointer, rather than its data value. Again,
|
||||||
|
* this is useful for the Nagios event queue.
|
||||||
|
*
|
||||||
|
* 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 "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
|
||||||
|
#include "../include/skiplist.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
skiplist *skiplist_new(int max_levels, float level_probability, int allow_duplicates, int append_duplicates, int (*compare_function)(void *, void *)) {
|
||||||
|
skiplist *newlist = NULL;
|
||||||
|
|
||||||
|
/* alloc memory for new list structure */
|
||||||
|
if((newlist = (skiplist *)malloc(sizeof(skiplist)))) {
|
||||||
|
|
||||||
|
/* initialize levels, etc. */
|
||||||
|
newlist->current_level = 0;
|
||||||
|
newlist->max_levels = max_levels;
|
||||||
|
newlist->level_probability = level_probability;
|
||||||
|
newlist->allow_duplicates = allow_duplicates;
|
||||||
|
newlist->append_duplicates = append_duplicates;
|
||||||
|
newlist->items = 0;
|
||||||
|
newlist->compare_function = compare_function;
|
||||||
|
|
||||||
|
/* initialize head node */
|
||||||
|
newlist->head = skiplist_new_node(newlist, max_levels);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int skiplist_insert(skiplist *list, void *data) {
|
||||||
|
skiplistnode **update = NULL;
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
skiplistnode *nextnode = NULL;
|
||||||
|
skiplistnode *newnode = NULL;
|
||||||
|
int level = 0;
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
if(list == NULL || data == NULL) {
|
||||||
|
return SKIPLIST_ERROR_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize update vector */
|
||||||
|
if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL) {
|
||||||
|
return SKIPLIST_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
for(x = 0; x < list->max_levels; x++)
|
||||||
|
update[x] = NULL;
|
||||||
|
|
||||||
|
/* check to make sure we don't have duplicates */
|
||||||
|
/* NOTE: this could made be more efficient */
|
||||||
|
if(list->allow_duplicates == FALSE) {
|
||||||
|
if(skiplist_find_first(list, data, NULL))
|
||||||
|
return SKIPLIST_ERROR_DUPLICATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find proper position for insert, remember pointers with an update vector */
|
||||||
|
thisnode = list->head;
|
||||||
|
for(level = list->current_level; level >= 0; level--) {
|
||||||
|
|
||||||
|
while((nextnode = thisnode->forward[level])) {
|
||||||
|
if(list->append_duplicates == TRUE) {
|
||||||
|
if(list->compare_function(nextnode->data, data) > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(list->compare_function(nextnode->data, data) >= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
thisnode = nextnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
update[level] = thisnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get a random level the new node should be inserted at */
|
||||||
|
level = skiplist_random_level(list);
|
||||||
|
/*printf("INSERTION LEVEL: %d\n",level);*/
|
||||||
|
|
||||||
|
/* we're adding a new level... */
|
||||||
|
if(level > list->current_level) {
|
||||||
|
/*printf("NEW LEVEL!\n");*/
|
||||||
|
list->current_level++;
|
||||||
|
level = list->current_level;
|
||||||
|
update[level] = list->head;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a new node */
|
||||||
|
if((newnode = skiplist_new_node(list, level)) == NULL) {
|
||||||
|
/*printf("NODE ERROR\n");*/
|
||||||
|
free(update);
|
||||||
|
return SKIPLIST_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
newnode->data = data;
|
||||||
|
|
||||||
|
/* update pointers to insert node at proper location */
|
||||||
|
do {
|
||||||
|
thisnode = update[level];
|
||||||
|
newnode->forward[level] = thisnode->forward[level];
|
||||||
|
thisnode->forward[level] = newnode;
|
||||||
|
|
||||||
|
}
|
||||||
|
while(--level >= 0);
|
||||||
|
|
||||||
|
/* update counters */
|
||||||
|
list->items++;
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
free(update);
|
||||||
|
|
||||||
|
return SKIPLIST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
skiplistnode *skiplist_new_node(skiplist *list, int node_levels) {
|
||||||
|
skiplistnode *newnode = NULL;
|
||||||
|
register int x = 0;
|
||||||
|
|
||||||
|
if(list == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(node_levels < 0 || node_levels > list->max_levels)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* allocate memory for node + variable number of level pointers */
|
||||||
|
if((newnode = (skiplistnode *)malloc(sizeof(skiplistnode) + (node_levels * sizeof(skiplistnode *))))) {
|
||||||
|
|
||||||
|
/* initialize forward pointers */
|
||||||
|
for(x = 0; x < node_levels; x++)
|
||||||
|
newnode->forward[x] = NULL;
|
||||||
|
|
||||||
|
/* initialize data pointer */
|
||||||
|
newnode->data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int skiplist_random_level(skiplist *list) {
|
||||||
|
int level = 0;
|
||||||
|
float r = 0.0;
|
||||||
|
|
||||||
|
if(list == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for(level = 0; level < list->max_levels; level++) {
|
||||||
|
r = ((float)rand() / (float)RAND_MAX);
|
||||||
|
if(r > list->level_probability)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (level >= list->max_levels) ? list->max_levels - 1 : level;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int skiplist_empty(skiplist *list) {
|
||||||
|
skiplistnode *this = NULL;
|
||||||
|
skiplistnode *next = NULL;
|
||||||
|
int level = 0;
|
||||||
|
|
||||||
|
if(list == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* free all list nodes (but not header) */
|
||||||
|
for(this = list->head->forward[0]; this != NULL; this = next) {
|
||||||
|
next = this->forward[0];
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset level pointers */
|
||||||
|
for(level = list->current_level; level >= 0; level--)
|
||||||
|
list->head->forward[level] = NULL;
|
||||||
|
|
||||||
|
/* reset list level */
|
||||||
|
list->current_level = 0;
|
||||||
|
|
||||||
|
/* reset items */
|
||||||
|
list->items = 0;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int skiplist_free(skiplist **list) {
|
||||||
|
skiplistnode *this = NULL;
|
||||||
|
skiplistnode *next = NULL;
|
||||||
|
|
||||||
|
if(list == NULL)
|
||||||
|
return ERROR;
|
||||||
|
if(*list == NULL)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
/* free header and all list nodes */
|
||||||
|
for(this = (*list)->head; this != NULL; this = next) {
|
||||||
|
next = this->forward[0];
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free list structure */
|
||||||
|
free(*list);
|
||||||
|
*list = NULL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* get first item in list */
|
||||||
|
void *skiplist_peek(skiplist *list) {
|
||||||
|
|
||||||
|
if(list == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* return first item */
|
||||||
|
return list->head->forward[0]->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* get/remove first item in list */
|
||||||
|
void *skiplist_pop(skiplist *list) {
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
void *data = NULL;
|
||||||
|
int level = 0;
|
||||||
|
|
||||||
|
if(list == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* get first item */
|
||||||
|
thisnode = list->head->forward[0];
|
||||||
|
if(thisnode == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* get data for first item */
|
||||||
|
data = thisnode->data;
|
||||||
|
|
||||||
|
/* remove first item from queue - update forward links from head to first node */
|
||||||
|
for(level = 0; level <= list->current_level; level++) {
|
||||||
|
if(list->head->forward[level] == thisnode)
|
||||||
|
list->head->forward[level] = thisnode->forward[level];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free deleted node */
|
||||||
|
free(thisnode);
|
||||||
|
|
||||||
|
/* adjust items */
|
||||||
|
list->items--;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* get first item in list */
|
||||||
|
void *skiplist_get_first(skiplist *list, void **node_ptr) {
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
|
||||||
|
if(list == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* get first node */
|
||||||
|
thisnode = list->head->forward[0];
|
||||||
|
|
||||||
|
/* return pointer to node */
|
||||||
|
if(node_ptr)
|
||||||
|
*node_ptr = (void *)thisnode;
|
||||||
|
|
||||||
|
if(thisnode)
|
||||||
|
return thisnode->data;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* get next item in list */
|
||||||
|
void *skiplist_get_next(void **node_ptr) {
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
skiplistnode *nextnode = NULL;
|
||||||
|
|
||||||
|
if(node_ptr == NULL || *node_ptr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
thisnode = (skiplistnode *)(*node_ptr);
|
||||||
|
nextnode = thisnode->forward[0];
|
||||||
|
|
||||||
|
*node_ptr = (void *)nextnode;
|
||||||
|
|
||||||
|
if(nextnode)
|
||||||
|
return nextnode->data;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* first first item in list */
|
||||||
|
void *skiplist_find_first(skiplist *list, void *data, void **node_ptr) {
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
skiplistnode *nextnode = NULL;
|
||||||
|
int level = 0;
|
||||||
|
|
||||||
|
if(list == NULL || data == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
thisnode = list->head;
|
||||||
|
for(level = list->current_level; level >= 0; level--) {
|
||||||
|
while((nextnode = thisnode->forward[level])) {
|
||||||
|
if(list->compare_function(nextnode->data, data) >= 0)
|
||||||
|
break;
|
||||||
|
thisnode = nextnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found it! */
|
||||||
|
if(nextnode && list->compare_function(nextnode->data, data) == 0) {
|
||||||
|
if(node_ptr)
|
||||||
|
*node_ptr = (void *)nextnode;
|
||||||
|
return nextnode->data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(node_ptr)
|
||||||
|
*node_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* find next match */
|
||||||
|
void *skiplist_find_next(skiplist *list, void *data, void **node_ptr) {
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
skiplistnode *nextnode = NULL;
|
||||||
|
|
||||||
|
if(list == NULL || data == NULL || node_ptr == NULL)
|
||||||
|
return NULL;
|
||||||
|
if(*node_ptr == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
thisnode = (skiplistnode *)(*node_ptr);
|
||||||
|
nextnode = thisnode->forward[0];
|
||||||
|
|
||||||
|
if(nextnode) {
|
||||||
|
if(list->compare_function(nextnode->data, data) == 0) {
|
||||||
|
*node_ptr = (void *)nextnode;
|
||||||
|
return nextnode->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*node_ptr = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* delete (all) matching item(s) from list */
|
||||||
|
int skiplist_delete(skiplist *list, void *data) {
|
||||||
|
|
||||||
|
return skiplist_delete_all(list, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* delete first matching item from list */
|
||||||
|
int skiplist_delete_first(skiplist *list, void *data) {
|
||||||
|
skiplistnode **update = NULL;
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
skiplistnode *nextnode = NULL;
|
||||||
|
int level = 0;
|
||||||
|
int top_level = 0;
|
||||||
|
int deleted = FALSE;
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
if(list == NULL || data == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* initialize update vector */
|
||||||
|
if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL)
|
||||||
|
return ERROR;
|
||||||
|
for(x = 0; x < list->max_levels; x++)
|
||||||
|
update[x] = NULL;
|
||||||
|
|
||||||
|
/* find location in list */
|
||||||
|
thisnode = list->head;
|
||||||
|
for(top_level = level = list->current_level; level >= 0; level--) {
|
||||||
|
while((nextnode = thisnode->forward[level])) {
|
||||||
|
if(list->compare_function(nextnode->data, data) >= 0)
|
||||||
|
break;
|
||||||
|
thisnode = nextnode;
|
||||||
|
}
|
||||||
|
update[level] = thisnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found a match! */
|
||||||
|
if(list->compare_function(nextnode->data, data) == 0) {
|
||||||
|
|
||||||
|
/* adjust level pointers to bypass (soon to be) removed node */
|
||||||
|
for(level = 0; level <= top_level; level++) {
|
||||||
|
|
||||||
|
thisnode = update[level];
|
||||||
|
if(thisnode->forward[level] != nextnode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
thisnode->forward[level] = nextnode->forward[level];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free node memory */
|
||||||
|
free(nextnode);
|
||||||
|
|
||||||
|
/* adjust top/current level of list is necessary */
|
||||||
|
while(list->head->forward[top_level] == NULL && top_level > 0)
|
||||||
|
top_level--;
|
||||||
|
list->current_level = top_level;
|
||||||
|
|
||||||
|
/* adjust items */
|
||||||
|
list->items--;
|
||||||
|
|
||||||
|
deleted = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
free(update);
|
||||||
|
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* delete all matching items from list */
|
||||||
|
int skiplist_delete_all(skiplist *list, void *data) {
|
||||||
|
int deleted = 0;
|
||||||
|
int total_deleted = 0;
|
||||||
|
|
||||||
|
/* NOTE: there is a more efficient way to do this... */
|
||||||
|
while((deleted = skiplist_delete_first(list, data)) == 1)
|
||||||
|
total_deleted++;
|
||||||
|
|
||||||
|
return total_deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* delete specific node from list */
|
||||||
|
int skiplist_delete_node(skiplist *list, void *node_ptr) {
|
||||||
|
void *data = NULL;
|
||||||
|
skiplistnode **update = NULL;
|
||||||
|
skiplistnode *thenode = NULL;
|
||||||
|
skiplistnode *thisnode = NULL;
|
||||||
|
skiplistnode *nextnode = NULL;
|
||||||
|
int level = 0;
|
||||||
|
int top_level = 0;
|
||||||
|
int deleted = FALSE;
|
||||||
|
int x = 0;
|
||||||
|
|
||||||
|
if(list == NULL || node_ptr == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* we'll need the data from the node to first find the node */
|
||||||
|
thenode = (skiplistnode *)node_ptr;
|
||||||
|
data = thenode->data;
|
||||||
|
|
||||||
|
/* initialize update vector */
|
||||||
|
if((update = (skiplistnode **)malloc(sizeof(skiplistnode *) * list->max_levels)) == NULL)
|
||||||
|
return ERROR;
|
||||||
|
for(x = 0; x < list->max_levels; x++)
|
||||||
|
update[x] = NULL;
|
||||||
|
|
||||||
|
/* find location in list */
|
||||||
|
thisnode = list->head;
|
||||||
|
for(top_level = level = list->current_level; level >= 0; level--) {
|
||||||
|
while((nextnode = thisnode->forward[level])) {
|
||||||
|
|
||||||
|
/* next node would be too far */
|
||||||
|
if(list->compare_function(nextnode->data, data) > 0)
|
||||||
|
break;
|
||||||
|
/* this is the exact node we want */
|
||||||
|
if(list->compare_function(nextnode->data, data) == 0 && nextnode == thenode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
thisnode = nextnode;
|
||||||
|
}
|
||||||
|
update[level] = thisnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found a match! (value + pointers match) */
|
||||||
|
if(nextnode && list->compare_function(nextnode->data, data) == 0 && nextnode == thenode) {
|
||||||
|
|
||||||
|
/* adjust level pointers to bypass (soon to be) removed node */
|
||||||
|
for(level = 0; level <= top_level; level++) {
|
||||||
|
|
||||||
|
thisnode = update[level];
|
||||||
|
if(thisnode->forward[level] != nextnode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
thisnode->forward[level] = nextnode->forward[level];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free node memory */
|
||||||
|
free(nextnode);
|
||||||
|
|
||||||
|
/* adjust top/current level of list is necessary */
|
||||||
|
while(list->head->forward[top_level] == NULL && top_level > 0)
|
||||||
|
top_level--;
|
||||||
|
list->current_level = top_level;
|
||||||
|
|
||||||
|
/* adjust items */
|
||||||
|
list->items--;
|
||||||
|
|
||||||
|
deleted = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
free(update);
|
||||||
|
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
1459
common/snprintf.c
Normal file
575
common/statusdata.c
Normal file
@ -0,0 +1,575 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* STATUSDATA.C - External status data for Nagios CGIs
|
||||||
|
*
|
||||||
|
* Copyright (c) 2000-2006 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 10-19-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.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*********** COMMON HEADER FILES ***********/
|
||||||
|
|
||||||
|
#include "../include/config.h"
|
||||||
|
#include "../include/common.h"
|
||||||
|
#include "../include/objects.h"
|
||||||
|
#include "../include/statusdata.h"
|
||||||
|
|
||||||
|
#ifdef NSCORE
|
||||||
|
#include "../include/nagios.h"
|
||||||
|
#include "../include/broker.h"
|
||||||
|
#endif
|
||||||
|
#ifdef NSCGI
|
||||||
|
#include "../include/cgiutils.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION SPECIFIC HEADER FILES ****/
|
||||||
|
|
||||||
|
#ifdef USE_XSDDEFAULT
|
||||||
|
#include "../xdata/xsddefault.h" /* default routines */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NSCORE
|
||||||
|
extern int aggregate_status_updates;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NSCGI
|
||||||
|
hoststatus *hoststatus_list = NULL;
|
||||||
|
hoststatus *hoststatus_list_tail = NULL;
|
||||||
|
servicestatus *servicestatus_list = NULL;
|
||||||
|
servicestatus *servicestatus_list_tail = NULL;
|
||||||
|
|
||||||
|
hoststatus **hoststatus_hashlist = NULL;
|
||||||
|
servicestatus **servicestatus_hashlist = NULL;
|
||||||
|
|
||||||
|
extern int use_pending_states;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NSCORE
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/****************** TOP-LEVEL OUTPUT FUNCTIONS ********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* initializes status data at program start */
|
||||||
|
int initialize_status_data(char *config_file) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XSDDEFAULT
|
||||||
|
result = xsddefault_initialize_status_data(config_file);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* update all status data (aggregated dump) */
|
||||||
|
int update_all_status_data(void) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_STARTDUMP, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XSDDEFAULT
|
||||||
|
result = xsddefault_save_status_data();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker */
|
||||||
|
broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_ENDDUMP, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(result != OK)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cleans up status data before program termination */
|
||||||
|
int cleanup_status_data(char *config_file, int delete_status_data) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XSDDEFAULT
|
||||||
|
result = xsddefault_cleanup_status_data(config_file, delete_status_data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* updates program status info */
|
||||||
|
int update_program_status(int aggregated_dump) {
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker (non-aggregated dumps only) */
|
||||||
|
if(aggregated_dump == FALSE)
|
||||||
|
broker_program_status(NEBTYPE_PROGRAMSTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* currently a noop if aggregated updates is TRUE */
|
||||||
|
|
||||||
|
/* update all status data if we're not aggregating updates */
|
||||||
|
if(aggregate_status_updates == FALSE)
|
||||||
|
update_all_status_data();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* updates host status info */
|
||||||
|
int update_host_status(host *hst, int aggregated_dump) {
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker (non-aggregated dumps only) */
|
||||||
|
if(aggregated_dump == FALSE)
|
||||||
|
broker_host_status(NEBTYPE_HOSTSTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, hst, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* currently a noop if aggregated updates is TRUE */
|
||||||
|
|
||||||
|
/* update all status data if we're not aggregating updates */
|
||||||
|
if(aggregate_status_updates == FALSE)
|
||||||
|
update_all_status_data();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* updates service status info */
|
||||||
|
int update_service_status(service *svc, int aggregated_dump) {
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker (non-aggregated dumps only) */
|
||||||
|
if(aggregated_dump == FALSE)
|
||||||
|
broker_service_status(NEBTYPE_SERVICESTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, svc, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* currently a noop if aggregated updates is TRUE */
|
||||||
|
|
||||||
|
/* update all status data if we're not aggregating updates */
|
||||||
|
if(aggregate_status_updates == FALSE)
|
||||||
|
update_all_status_data();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* updates contact status info */
|
||||||
|
int update_contact_status(contact *cntct, int aggregated_dump) {
|
||||||
|
|
||||||
|
#ifdef USE_EVENT_BROKER
|
||||||
|
/* send data to event broker (non-aggregated dumps only) */
|
||||||
|
if(aggregated_dump == FALSE)
|
||||||
|
broker_contact_status(NEBTYPE_CONTACTSTATUS_UPDATE, NEBFLAG_NONE, NEBATTR_NONE, cntct, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* currently a noop if aggregated updates is TRUE */
|
||||||
|
|
||||||
|
/* update all status data if we're not aggregating updates */
|
||||||
|
if(aggregate_status_updates == FALSE)
|
||||||
|
update_all_status_data();
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NSCGI
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/******************* TOP-LEVEL INPUT FUNCTIONS ********************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* reads in all status data */
|
||||||
|
int read_status_data(char *config_file, int options) {
|
||||||
|
int result = OK;
|
||||||
|
|
||||||
|
/**** IMPLEMENTATION-SPECIFIC CALLS ****/
|
||||||
|
#ifdef USE_XSDDEFAULT
|
||||||
|
result = xsddefault_read_status_data(config_file, options);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_XSDDB
|
||||||
|
result = xsddb_read_status_data(config_file, options);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/****************** CHAINED HASH FUNCTIONS ************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/* adds hoststatus to hash list in memory */
|
||||||
|
int add_hoststatus_to_hashlist(hoststatus *new_hoststatus) {
|
||||||
|
hoststatus *temp_hoststatus = NULL;
|
||||||
|
hoststatus *lastpointer = NULL;
|
||||||
|
int hashslot = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/* initialize hash list */
|
||||||
|
if(hoststatus_hashlist == NULL) {
|
||||||
|
|
||||||
|
hoststatus_hashlist = (hoststatus **)malloc(sizeof(hoststatus *) * HOSTSTATUS_HASHSLOTS);
|
||||||
|
if(hoststatus_hashlist == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(i = 0; i < HOSTSTATUS_HASHSLOTS; i++)
|
||||||
|
hoststatus_hashlist[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!new_hoststatus)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
hashslot = hashfunc(new_hoststatus->host_name, NULL, HOSTSTATUS_HASHSLOTS);
|
||||||
|
lastpointer = NULL;
|
||||||
|
for(temp_hoststatus = hoststatus_hashlist[hashslot]; temp_hoststatus && compare_hashdata(temp_hoststatus->host_name, NULL, new_hoststatus->host_name, NULL) < 0; temp_hoststatus = temp_hoststatus->nexthash)
|
||||||
|
lastpointer = temp_hoststatus;
|
||||||
|
|
||||||
|
if(!temp_hoststatus || (compare_hashdata(temp_hoststatus->host_name, NULL, new_hoststatus->host_name, NULL) != 0)) {
|
||||||
|
if(lastpointer)
|
||||||
|
lastpointer->nexthash = new_hoststatus;
|
||||||
|
else
|
||||||
|
hoststatus_hashlist[hashslot] = new_hoststatus;
|
||||||
|
new_hoststatus->nexthash = temp_hoststatus;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* else already exists */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int add_servicestatus_to_hashlist(servicestatus *new_servicestatus) {
|
||||||
|
servicestatus *temp_servicestatus = NULL, *lastpointer = NULL;
|
||||||
|
int hashslot = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/* initialize hash list */
|
||||||
|
if(servicestatus_hashlist == NULL) {
|
||||||
|
|
||||||
|
servicestatus_hashlist = (servicestatus **)malloc(sizeof(servicestatus *) * SERVICESTATUS_HASHSLOTS);
|
||||||
|
if(servicestatus_hashlist == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(i = 0; i < SERVICESTATUS_HASHSLOTS; i++)
|
||||||
|
servicestatus_hashlist[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!new_servicestatus)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
hashslot = hashfunc(new_servicestatus->host_name, new_servicestatus->description, SERVICESTATUS_HASHSLOTS);
|
||||||
|
lastpointer = NULL;
|
||||||
|
for(temp_servicestatus = servicestatus_hashlist[hashslot]; temp_servicestatus && compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, new_servicestatus->host_name, new_servicestatus->description) < 0; temp_servicestatus = temp_servicestatus->nexthash)
|
||||||
|
lastpointer = temp_servicestatus;
|
||||||
|
|
||||||
|
if(!temp_servicestatus || (compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, new_servicestatus->host_name, new_servicestatus->description) != 0)) {
|
||||||
|
if(lastpointer)
|
||||||
|
lastpointer->nexthash = new_servicestatus;
|
||||||
|
else
|
||||||
|
servicestatus_hashlist[hashslot] = new_servicestatus;
|
||||||
|
new_servicestatus->nexthash = temp_servicestatus;
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* else already exists */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/********************** ADDITION FUNCTIONS ************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a host status entry to the list in memory */
|
||||||
|
int add_host_status(hoststatus *new_hoststatus) {
|
||||||
|
char date_string[MAX_DATETIME_LENGTH];
|
||||||
|
|
||||||
|
/* make sure we have what we need */
|
||||||
|
if(new_hoststatus == NULL)
|
||||||
|
return ERROR;
|
||||||
|
if(new_hoststatus->host_name == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* massage host status a bit */
|
||||||
|
if(new_hoststatus != NULL) {
|
||||||
|
switch(new_hoststatus->status) {
|
||||||
|
case 0:
|
||||||
|
new_hoststatus->status = HOST_UP;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
new_hoststatus->status = HOST_DOWN;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
new_hoststatus->status = HOST_UNREACHABLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
new_hoststatus->status = HOST_UP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(new_hoststatus->has_been_checked == FALSE) {
|
||||||
|
if(use_pending_states == TRUE)
|
||||||
|
new_hoststatus->status = HOST_PENDING;
|
||||||
|
my_free(new_hoststatus->plugin_output);
|
||||||
|
if(new_hoststatus->should_be_scheduled == TRUE) {
|
||||||
|
get_time_string(&new_hoststatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
||||||
|
asprintf(&new_hoststatus->plugin_output, "Host check scheduled for %s", date_string);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* passive-only hosts that have just been scheduled for a forced check */
|
||||||
|
if(new_hoststatus->checks_enabled == FALSE && new_hoststatus->next_check != (time_t)0L && (new_hoststatus->check_options & CHECK_OPTION_FORCE_EXECUTION)) {
|
||||||
|
get_time_string(&new_hoststatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
||||||
|
asprintf(&new_hoststatus->plugin_output, "Forced host check scheduled for %s", date_string);
|
||||||
|
}
|
||||||
|
/* passive-only hosts not scheduled to be checked */
|
||||||
|
else
|
||||||
|
new_hoststatus->plugin_output = (char *)strdup("Host is not scheduled to be checked...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_hoststatus->next = NULL;
|
||||||
|
new_hoststatus->nexthash = NULL;
|
||||||
|
|
||||||
|
/* add new hoststatus to hoststatus chained hash list */
|
||||||
|
if(!add_hoststatus_to_hashlist(new_hoststatus))
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* object cache file is already sorted, so just add new items to end of list */
|
||||||
|
if(hoststatus_list == NULL) {
|
||||||
|
hoststatus_list = new_hoststatus;
|
||||||
|
hoststatus_list_tail = new_hoststatus;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hoststatus_list_tail->next = new_hoststatus;
|
||||||
|
hoststatus_list_tail = new_hoststatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* adds a service status entry to the list in memory */
|
||||||
|
int add_service_status(servicestatus *new_svcstatus) {
|
||||||
|
char date_string[MAX_DATETIME_LENGTH];
|
||||||
|
|
||||||
|
/* make sure we have what we need */
|
||||||
|
if(new_svcstatus == NULL)
|
||||||
|
return ERROR;
|
||||||
|
if(new_svcstatus->host_name == NULL || new_svcstatus->description == NULL)
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
|
||||||
|
/* massage service status a bit */
|
||||||
|
if(new_svcstatus != NULL) {
|
||||||
|
switch(new_svcstatus->status) {
|
||||||
|
case 0:
|
||||||
|
new_svcstatus->status = SERVICE_OK;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
new_svcstatus->status = SERVICE_WARNING;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
new_svcstatus->status = SERVICE_CRITICAL;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
new_svcstatus->status = SERVICE_UNKNOWN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
new_svcstatus->status = SERVICE_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(new_svcstatus->has_been_checked == FALSE) {
|
||||||
|
if(use_pending_states == TRUE)
|
||||||
|
new_svcstatus->status = SERVICE_PENDING;
|
||||||
|
my_free(new_svcstatus->plugin_output);
|
||||||
|
if(new_svcstatus->should_be_scheduled == TRUE) {
|
||||||
|
get_time_string(&new_svcstatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
||||||
|
asprintf(&new_svcstatus->plugin_output, "Service check scheduled for %s", date_string);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* passive-only services that have just been scheduled for a forced check */
|
||||||
|
if(new_svcstatus->checks_enabled == FALSE && new_svcstatus->next_check != (time_t)0L && (new_svcstatus->check_options & CHECK_OPTION_FORCE_EXECUTION)) {
|
||||||
|
get_time_string(&new_svcstatus->next_check, date_string, sizeof(date_string), LONG_DATE_TIME);
|
||||||
|
asprintf(&new_svcstatus->plugin_output, "Forced service check scheduled for %s", date_string);
|
||||||
|
}
|
||||||
|
/* passive-only services not scheduled to be checked */
|
||||||
|
else
|
||||||
|
new_svcstatus->plugin_output = (char *)strdup("Service is not scheduled to be checked...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_svcstatus->next = NULL;
|
||||||
|
new_svcstatus->nexthash = NULL;
|
||||||
|
|
||||||
|
/* add new servicestatus to servicestatus chained hash list */
|
||||||
|
if(!add_servicestatus_to_hashlist(new_svcstatus))
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
/* object cache file is already sorted, so just add new items to end of list */
|
||||||
|
if(servicestatus_list == NULL) {
|
||||||
|
servicestatus_list = new_svcstatus;
|
||||||
|
servicestatus_list_tail = new_svcstatus;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
servicestatus_list_tail->next = new_svcstatus;
|
||||||
|
servicestatus_list_tail = new_svcstatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/*********************** CLEANUP FUNCTIONS ************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* free all memory for status data */
|
||||||
|
void free_status_data(void) {
|
||||||
|
hoststatus *this_hoststatus = NULL;
|
||||||
|
hoststatus *next_hoststatus = NULL;
|
||||||
|
servicestatus *this_svcstatus = NULL;
|
||||||
|
servicestatus *next_svcstatus = NULL;
|
||||||
|
|
||||||
|
/* free memory for the host status list */
|
||||||
|
for(this_hoststatus = hoststatus_list; this_hoststatus != NULL; this_hoststatus = next_hoststatus) {
|
||||||
|
next_hoststatus = this_hoststatus->next;
|
||||||
|
my_free(this_hoststatus->host_name);
|
||||||
|
my_free(this_hoststatus->plugin_output);
|
||||||
|
my_free(this_hoststatus->long_plugin_output);
|
||||||
|
my_free(this_hoststatus->perf_data);
|
||||||
|
my_free(this_hoststatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free memory for the service status list */
|
||||||
|
for(this_svcstatus = servicestatus_list; this_svcstatus != NULL; this_svcstatus = next_svcstatus) {
|
||||||
|
next_svcstatus = this_svcstatus->next;
|
||||||
|
my_free(this_svcstatus->host_name);
|
||||||
|
my_free(this_svcstatus->description);
|
||||||
|
my_free(this_svcstatus->plugin_output);
|
||||||
|
my_free(this_svcstatus->long_plugin_output);
|
||||||
|
my_free(this_svcstatus->perf_data);
|
||||||
|
my_free(this_svcstatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free hash lists reset list pointers */
|
||||||
|
my_free(hoststatus_hashlist);
|
||||||
|
my_free(servicestatus_hashlist);
|
||||||
|
hoststatus_list = NULL;
|
||||||
|
servicestatus_list = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/************************ SEARCH FUNCTIONS ************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* find a host status entry */
|
||||||
|
hoststatus *find_hoststatus(char *host_name) {
|
||||||
|
hoststatus *temp_hoststatus = NULL;
|
||||||
|
|
||||||
|
if(host_name == NULL || hoststatus_hashlist == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for(temp_hoststatus = hoststatus_hashlist[hashfunc(host_name, NULL, HOSTSTATUS_HASHSLOTS)]; temp_hoststatus && compare_hashdata(temp_hoststatus->host_name, NULL, host_name, NULL) < 0; temp_hoststatus = temp_hoststatus->nexthash);
|
||||||
|
|
||||||
|
if(temp_hoststatus && (compare_hashdata(temp_hoststatus->host_name, NULL, host_name, NULL) == 0))
|
||||||
|
return temp_hoststatus;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* find a service status entry */
|
||||||
|
servicestatus *find_servicestatus(char *host_name, char *svc_desc) {
|
||||||
|
servicestatus *temp_servicestatus = NULL;
|
||||||
|
|
||||||
|
if(host_name == NULL || svc_desc == NULL || servicestatus_hashlist == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for(temp_servicestatus = servicestatus_hashlist[hashfunc(host_name, svc_desc, SERVICESTATUS_HASHSLOTS)]; temp_servicestatus && compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, host_name, svc_desc) < 0; temp_servicestatus = temp_servicestatus->nexthash);
|
||||||
|
|
||||||
|
if(temp_servicestatus && (compare_hashdata(temp_servicestatus->host_name, temp_servicestatus->description, host_name, svc_desc) == 0))
|
||||||
|
return temp_servicestatus;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/*********************** UTILITY FUNCTIONS ************************/
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* gets the total number of services of a certain state for a specific host */
|
||||||
|
int get_servicestatus_count(char *host_name, int type) {
|
||||||
|
servicestatus *temp_status = NULL;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
if(host_name == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(temp_status = servicestatus_list; temp_status != NULL; temp_status = temp_status->next) {
|
||||||
|
if(temp_status->status & type) {
|
||||||
|
if(!strcmp(host_name, temp_status->host_name))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
1510
config.guess
vendored
Executable file
1619
config.sub
vendored
Executable file
880
configure.in
Normal file
@ -0,0 +1,880 @@
|
|||||||
|
dnl Process this -*-m4-*- file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
dnl Disable caching
|
||||||
|
define([AC_CACHE_LOAD],)
|
||||||
|
define([AC_CACHE_SAVE],)
|
||||||
|
|
||||||
|
AC_INIT(base/nagios.c)
|
||||||
|
AC_CONFIG_HEADER(include/config.h include/snprintf.h)
|
||||||
|
AC_PREFIX_DEFAULT(/usr/local/nagios)
|
||||||
|
|
||||||
|
PKG_NAME=nagios
|
||||||
|
PKG_VERSION="3.5.1"
|
||||||
|
PKG_HOME_URL="http://www.nagios.org/"
|
||||||
|
PKG_REL_DATE="08-30-2013"
|
||||||
|
|
||||||
|
dnl Figure out how to invoke "install" and what install options to use.
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_SUBST(INSTALL)
|
||||||
|
|
||||||
|
dnl What OS are we running?
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
|
dnl Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
AC_PATH_PROG([STRIP],[strip],[true])
|
||||||
|
|
||||||
|
dnl Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_HEADER_TIME
|
||||||
|
AC_HEADER_SYS_WAIT
|
||||||
|
AC_CHECK_HEADERS(arpa/inet.h ctype.h dirent.h errno.h fcntl.h getopt.h grp.h libgen.h limits.h math.h netdb.h netinet/in.h pthread.h pthreads.h pwd.h regex.h signal.h socket.h stdarg.h string.h strings.h sys/mman.h sys/types.h sys/time.h sys/resource.h sys/wait.h sys/socket.h sys/stat.h sys/timeb.h sys/un.h sys/ipc.h sys/msg.h sys/poll.h syslog.h uio.h unistd.h locale.h wchar.h)
|
||||||
|
|
||||||
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_CONST
|
||||||
|
AC_STRUCT_TM
|
||||||
|
AC_STRUCT_TIMEZONE
|
||||||
|
AC_TYPE_MODE_T
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
AC_TYPE_GETGROUPS
|
||||||
|
|
||||||
|
|
||||||
|
dnl Check for asprintf() and friends...
|
||||||
|
AC_CACHE_CHECK([for va_copy],ac_cv_HAVE_VA_COPY,[
|
||||||
|
AC_TRY_LINK([#include <stdarg.h>
|
||||||
|
va_list ap1,ap2;], [va_copy(ap1,ap2);],
|
||||||
|
ac_cv_HAVE_VA_COPY=yes,
|
||||||
|
ac_cv_HAVE_VA_COPY=no)])
|
||||||
|
if test x"$ac_cv_HAVE_VA_COPY" = x"yes"; then
|
||||||
|
AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available])
|
||||||
|
else
|
||||||
|
AC_CACHE_CHECK([for __va_copy],ac_cv_HAVE___VA_COPY,[
|
||||||
|
AC_TRY_LINK([#include <stdarg.h>
|
||||||
|
va_list ap1,ap2;], [__va_copy(ap1,ap2);],
|
||||||
|
ac_cv_HAVE___VA_COPY=yes,
|
||||||
|
ac_cv_HAVE___VA_COPY=no)])
|
||||||
|
if test x"$ac_cv_HAVE___VA_COPY" = x"yes"; then
|
||||||
|
AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_FUNC(vsnprintf,,SNPRINTF_O=../common/snprintf.o)
|
||||||
|
AC_CHECK_FUNC(snprintf,,SNPRINTF_O=../common/snprintf.o)
|
||||||
|
AC_CHECK_FUNC(asprintf,,SNPRINTF_O=../common/snprintf.o)
|
||||||
|
AC_CHECK_FUNC(vasprintf,,SNPRINTF_O=../common/snprintf.o)
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([for C99 vsnprintf],ac_cv_HAVE_C99_VSNPRINTF,[
|
||||||
|
AC_TRY_RUN([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
void foo(const char *format, ...) {
|
||||||
|
va_list ap;
|
||||||
|
int len;
|
||||||
|
char buf[5];
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
len = vsnprintf(buf, 0, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (len != 5) exit(1);
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
len = vsnprintf(0, 0, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (len != 5) exit(1);
|
||||||
|
|
||||||
|
if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
main() { foo("hello"); }
|
||||||
|
],
|
||||||
|
ac_cv_HAVE_C99_VSNPRINTF=yes,ac_cv_HAVE_C99_VSNPRINTF=no,ac_cv_HAVE_C99_VSNPRINTF=cross)])
|
||||||
|
if test x"$ac_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
|
||||||
|
AC_DEFINE(HAVE_C99_VSNPRINTF,1,[Define if system has C99 compatible vsnprintf])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl AC_CHECK_FUNC(snprintf,AC_DEFINE(HAVE_SNPRINTF),SNPRINTF_O=../common/snprintf.o)
|
||||||
|
AC_SUBST(SNPRINTF_O)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Checks for library functions.
|
||||||
|
AC_SEARCH_LIBS([getservbyname],[nsl],
|
||||||
|
[if test "$ac_cv_search_getservbyname" != "none required"; then
|
||||||
|
SOCKETLIBS="$SOCKETLIBS -lnsl"
|
||||||
|
fi])
|
||||||
|
AC_SEARCH_LIBS([connect],[socket],
|
||||||
|
[if test "$ac_cv_search_connect" != "none required"; then
|
||||||
|
SOCKETLIBS="$SOCKETLIBS -lsocket"
|
||||||
|
fi])
|
||||||
|
AC_SUBST(SOCKETLIBS)
|
||||||
|
AC_CHECK_FUNCS(initgroups setenv strdup strstr strtoul unsetenv)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(for type of socket size)
|
||||||
|
AC_TRY_COMPILE([#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
],
|
||||||
|
[int a = send(1, (const void *) 0, (size_t) 0, (int) 0);],
|
||||||
|
[AC_DEFINE(SOCKET_SIZE_TYPE, size_t, [typedef for socket size]) AC_MSG_RESULT(size_t)],
|
||||||
|
[AC_DEFINE(SOCKET_SIZE_TYPE, int, [typedef for socket size]) AC_MSG_RESULT(int)])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Test for pthreads support - taken from ICU FreeBSD Port configure script
|
||||||
|
THREADLIBS=""
|
||||||
|
have_pthreads="no"
|
||||||
|
|
||||||
|
dnl FreeBSD: Try ports/linuxthreads first - Mammad Zadeh <mammad@yahoo-inc.com>
|
||||||
|
dnl FreeBSD -pthread check - Jonathan McDowell <noodles@earth.li>
|
||||||
|
AC_DEFUN([AC_PTHREAD_FREEBSD],[
|
||||||
|
AC_CHECK_LIB(lthread,pthread_create,[
|
||||||
|
CFLAGS="-D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -I/usr/include $CFLAGS"
|
||||||
|
THREADLIBS="-L/usr/local/lib -llthread -llgcc_r"
|
||||||
|
],[
|
||||||
|
AC_MSG_CHECKING([if we need -pthread for threads])
|
||||||
|
AC_CACHE_VAL(ac_ldflag_pthread,[
|
||||||
|
ac_save_LDFLAGS="$LDFLAGS"
|
||||||
|
LDFLAGS="-pthread $LDFLAGS"
|
||||||
|
AC_TRY_LINK([
|
||||||
|
char pthread_create();
|
||||||
|
],
|
||||||
|
pthread_create();,
|
||||||
|
eval "ac_ldflag_pthread=yes",
|
||||||
|
eval "ac_ldflag_pthread=no"
|
||||||
|
),
|
||||||
|
THREADLIBS="$ac_save_LDFLAGS"
|
||||||
|
])
|
||||||
|
if eval "test \"`echo $ac_ldflag_pthread`\" = yes"; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
],-L/usr/local/lib)
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Test for HPUX cma threads first..
|
||||||
|
AC_CHECK_LIB(cma,pthread_create,THREADLIBS="$THREADLIBS -lpthread")
|
||||||
|
if test $ac_cv_lib_cma_pthread_create = yes; then
|
||||||
|
have_pthreads="yes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl special pthread handling
|
||||||
|
dnl AIX uses pthreads instead of pthread, and HP/UX uses cma
|
||||||
|
dnl FreeBSD users -pthread
|
||||||
|
AC_CHECK_LIB(pthread,pthread_create,THREADLIBS="$THREADLIBS -lpthread")
|
||||||
|
if test $ac_cv_lib_pthread_pthread_create = yes; then
|
||||||
|
have_pthreads="yes"
|
||||||
|
else
|
||||||
|
dnl For HP 11
|
||||||
|
AC_CHECK_LIB(pthread,pthread_mutex_init,THREADLIBS="$THREADLIBS -lpthread")
|
||||||
|
if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
|
||||||
|
have_pthreads="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl AIX uses pthreads instead of pthread
|
||||||
|
if test $have_pthreads = "no"; then
|
||||||
|
AC_CHECK_LIB(pthreads,pthread_create,THREADLIBS="$THREADLIBS -lpthreads")
|
||||||
|
if test $ac_cv_lib_pthreads_pthread_create = yes; then
|
||||||
|
have_pthreads="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl all other thread tests fail, try BSD's -pthread
|
||||||
|
if test $have_pthreads = "no"; then
|
||||||
|
AC_PTHREAD_FREEBSD
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(THREADLIBS)
|
||||||
|
|
||||||
|
dnl Solaris needs rt or posix4 libraries for nanosleep()
|
||||||
|
AC_SEARCH_LIBS(nanosleep,[rt posix4],,[
|
||||||
|
echo "Error: nanosleep() needed for timing operations."
|
||||||
|
exit 1
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_ARG_WITH(nagios_user,AC_HELP_STRING([--with-nagios-user=<user>],[sets user name to run nagios]),nagios_user=$withval,nagios_user=nagios)
|
||||||
|
AC_ARG_WITH(nagios_group,AC_HELP_STRING([--with-nagios-group=<grp>],[sets group name to run nagios]),nagios_grp=$withval,nagios_grp=nagios)
|
||||||
|
AC_SUBST(nagios_user)
|
||||||
|
AC_SUBST(nagios_grp)
|
||||||
|
AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_USER,"$nagios_user",[user name to run nagios])
|
||||||
|
AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_GROUP,"$nagios_grp",[group name to run nagios])
|
||||||
|
INSTALL_OPTS="-o $nagios_user -g $nagios_grp"
|
||||||
|
AC_SUBST(INSTALL_OPTS)
|
||||||
|
|
||||||
|
AC_ARG_WITH(command_user,AC_HELP_STRING([--with-command-user=<user>],[sets user name for command access]),command_user=$withval,command_user=$nagios_user)
|
||||||
|
AC_ARG_WITH(command_group,AC_HELP_STRING([--with-command-group=<grp>],[sets group name for command access]),command_grp=$withval,command_grp=$nagios_grp)
|
||||||
|
AC_SUBST(command_user)
|
||||||
|
AC_SUBST(command_grp)
|
||||||
|
COMMAND_OPTS="-o $command_user -g $command_grp"
|
||||||
|
AC_SUBST(COMMAND_OPTS)
|
||||||
|
|
||||||
|
dnl Check for location of mail program
|
||||||
|
MAIL_PROG=no
|
||||||
|
AC_ARG_WITH(mail,--with-mail=<path_to_mail> sets path to equivalent program to mail,MAIL_PROG=$withval,MAIL_PROG=no)
|
||||||
|
if test x$MAIL_PROG = xno; then
|
||||||
|
AC_PATH_PROG(MAIL_PROG,mail)
|
||||||
|
fi
|
||||||
|
dnl Fix for systems that don't (yet) have mail/mailx installed...
|
||||||
|
if test x$MAIL_PROG = x; then
|
||||||
|
MAIL_PROG="/bin/mail"
|
||||||
|
fi
|
||||||
|
AC_SUBST(MAIL_PROG)
|
||||||
|
|
||||||
|
dnl Check for location of Apache conf.d directory
|
||||||
|
HTTP_CONF=no
|
||||||
|
AC_ARG_WITH(httpd_conf,--with-httpd-conf=<path_to_conf> sets path to Apache conf.d directory,HTTPD_CONF=$withval,HTTPD_CONF=no)
|
||||||
|
if test x$HTTPD_CONF = xno; then
|
||||||
|
if test -d /etc/httpd/conf.d; then
|
||||||
|
HTTPD_CONF="/etc/httpd/conf.d"
|
||||||
|
elif test -d /etc/apache2/conf.d; then
|
||||||
|
HTTPD_CONF="/etc/apache2/conf.d"
|
||||||
|
elif test -d /etc/apache/conf.d; then
|
||||||
|
HTTPD_CONF="/etc/apache/conf.d"
|
||||||
|
else
|
||||||
|
HTTPD_CONF="/etc/httpd/conf.d"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AC_SUBST(HTTPD_CONF)
|
||||||
|
|
||||||
|
dnl Location of check result path
|
||||||
|
CHECKRESULTDIR=no
|
||||||
|
AC_ARG_WITH(checkresult-dir,--with-checkresult-dir=<path> sets path to check results spool directory,CHECKRESULTDIR=$withval,CHECKRESULTDIR=no)
|
||||||
|
if test x$CHECKRESULTDIR = xno; then
|
||||||
|
CHECKRESULTDIR="$localstatedir/spool/checkresults"
|
||||||
|
fi
|
||||||
|
AC_SUBST(CHECKRESULTDIR)
|
||||||
|
|
||||||
|
dnl Location of check result path
|
||||||
|
TMPDIR=no
|
||||||
|
AC_ARG_WITH(temp-dir,--with-temp-dir=<path> sets path to temp directory,TMPDIR=$withval,TMPDIR=no)
|
||||||
|
if test x$TMPDIR = xno; then
|
||||||
|
TMPDIR="/tmp"
|
||||||
|
fi
|
||||||
|
AC_SUBST(TMPDIR)
|
||||||
|
|
||||||
|
dnl Check for location of init scripts
|
||||||
|
init_dir=/etc/rc.d/init.d
|
||||||
|
if test -d /etc/rc.d/init.d; then
|
||||||
|
init_dir="/etc/rc.d/init.d"
|
||||||
|
elif test -d /usr/local/etc/rc.d; then
|
||||||
|
init_dir="/usr/local/etc/rc.d"
|
||||||
|
elif test -d /etc/rc.d; then
|
||||||
|
init_dir="/etc/rc.d"
|
||||||
|
elif test -d /etc/init.d; then
|
||||||
|
init_dir="/etc/init.d"
|
||||||
|
elif test -d /sbin/init.d; then
|
||||||
|
init_dir="/sbin/init.d"
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl User can override init script location
|
||||||
|
AC_ARG_WITH(init_dir,--with-init-dir=<path> sets directory to place init script into,init_dir=$withval)
|
||||||
|
AC_SUBST(init_dir)
|
||||||
|
|
||||||
|
dnl User can override lock file location
|
||||||
|
AC_ARG_WITH(lockfile,--with-lockfile=<path> sets path and file name for lock file,lockfile=$withval,lockfile=$localstatedir/nagios.lock)
|
||||||
|
AC_SUBST(lockfile)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dnl Default xdata routines...
|
||||||
|
XSDTYPE=default
|
||||||
|
XCDTYPE=default
|
||||||
|
XRDTYPE=default
|
||||||
|
XODTYPE=template
|
||||||
|
XPDTYPE=default
|
||||||
|
XDDTYPE=default
|
||||||
|
|
||||||
|
XSDCOMMENT=
|
||||||
|
XCDCOMMENT=
|
||||||
|
XRDCOMMENT=
|
||||||
|
XODCOMMENT=
|
||||||
|
XPDCOMMENT=
|
||||||
|
XDDCOMMENT=
|
||||||
|
|
||||||
|
USE_MYSQL=no
|
||||||
|
USE_PGSQL=no
|
||||||
|
|
||||||
|
dnl Status data
|
||||||
|
AC_DEFINE_UNQUOTED(USE_XSDDEFAULT,,[use default routines (in xdata/xsddefault.*) for status data I/O...])
|
||||||
|
XSDC="xsddefault.c"
|
||||||
|
XSDH="xsddefault.h"
|
||||||
|
XSDCOMMENT="Default (text file)"
|
||||||
|
echo "We'll use default routines (in xdata/xsddefault.*) for status data I/O..."
|
||||||
|
AC_SUBST(XSDC)
|
||||||
|
AC_SUBST(XSDH)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Comment data
|
||||||
|
AC_DEFINE_UNQUOTED(USE_XCDDEFAULT,,[use default routines (in xdata/xcddefault.*) for comment data I/O...])
|
||||||
|
XCDC="xcddefault.c"
|
||||||
|
XCDH="xcddefault.h"
|
||||||
|
XCDCOMMENT="Default (text file)"
|
||||||
|
echo "We'll use default routines (in xdata/xcddefault.*) for comment data I/O..."
|
||||||
|
AC_SUBST(XCDC)
|
||||||
|
AC_SUBST(XCDH)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Retention data
|
||||||
|
AC_DEFINE_UNQUOTED(USE_XRDDEFAULT,,[use default routines (in xdata/xrddefault.*) for retention data I/O...])
|
||||||
|
XRDC="xrddefault.c"
|
||||||
|
XRDH="xrddefault.h"
|
||||||
|
XRDCOMMENT="Default (text file)"
|
||||||
|
echo "We'll use default routines (in xdata/xrddefault.*) for retention data I/O..."
|
||||||
|
AC_SUBST(XRDC)
|
||||||
|
AC_SUBST(XRDH)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Object data
|
||||||
|
AC_DEFINE_UNQUOTED(USE_XODTEMPLATE,,[use template-based routines (in xdata/xodtemplate.*) for object data I/O...])
|
||||||
|
XODC="xodtemplate.c"
|
||||||
|
XODH="xodtemplate.h"
|
||||||
|
XODCOMMENT="Template-based (text file)"
|
||||||
|
echo "We'll use template-based routines (in xdata/xodtemplate.*) for object data I/O..."
|
||||||
|
AC_SUBST(XODC)
|
||||||
|
AC_SUBST(XODH)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dnl Performance data
|
||||||
|
AC_DEFINE_UNQUOTED(USE_XPDDEFAULT,,[use default routines (in xdata/xpddefault.*) for performance data I/O...])
|
||||||
|
XPDC="xpddefault.c"
|
||||||
|
XPDH="xpddefault.h"
|
||||||
|
XPDCOMMENT="Default (external commands)"
|
||||||
|
echo "We'll use default routines (in xdata/xpddefault.*) for performance data I/O..."
|
||||||
|
AC_SUBST(XPDC)
|
||||||
|
AC_SUBST(XPDH)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Downtime data
|
||||||
|
AC_DEFINE_UNQUOTED(USE_XDDDEFAULT,,[use default routines (in xdata/xdddefault.*) for scheduled downtime data I/O...])
|
||||||
|
XDDC="xdddefault.c"
|
||||||
|
XDDH="xdddefault.h"
|
||||||
|
XDDCOMMENT="Default (text file)"
|
||||||
|
echo "We'll use default routines (in xdata/xdddefault.*) for scheduled downtime data I/O..."
|
||||||
|
AC_SUBST(XDDC)
|
||||||
|
AC_SUBST(XDDH)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Optional GD library and include paths
|
||||||
|
AC_ARG_WITH(gd-lib,--with-gd-lib=DIR sets location of the gd library,[
|
||||||
|
LDFLAGS="${LDFLAGS} -L${withval}"
|
||||||
|
LD_RUN_PATH="${withval}${LD_RUN_PATH:+:}${LD_RUN_PATH}"
|
||||||
|
])
|
||||||
|
AC_ARG_WITH(gd-inc,--with-gd-inc=DIR sets location of the gd include files,[
|
||||||
|
CFLAGS="${CFLAGS} -I${withval}"
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
TRYGD=yep
|
||||||
|
|
||||||
|
dnl statusmap CGI enabled by default, unless users chooses not to use it
|
||||||
|
TRYSTATUSMAP=yep
|
||||||
|
AC_ARG_ENABLE(statusmap,--disable-statusmap=disables compilation of statusmap CGI,TRYSTATUSMAP=nope)
|
||||||
|
|
||||||
|
|
||||||
|
dnl statuswrl CGI enabled by default, unless users chooses not to use it
|
||||||
|
TRYSTATUSWRL=yep
|
||||||
|
AC_ARG_ENABLE(statuswrl,--disable-statuswrl=disables compilation of statuswrl (VRML) CGI,TRYSTATUSWRL=nope)
|
||||||
|
|
||||||
|
if test x$TRYSTATUSWRL = xyep; then
|
||||||
|
AC_DEFINE_UNQUOTED(USE_STATUSWRL,,[statuswrl CGI enabled by default, unless users chooses not to use it])
|
||||||
|
CGIEXTRAS="$CGIEXTRAS statuswrl.cgi"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl JMD_CHECK_LIB_ORDER(LIBRARY, FUNCTION, ORDER [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND
|
||||||
|
dnl [, OTHER-LIBRARIES]]])
|
||||||
|
AC_DEFUN([JMD_CHECK_LIB_ORDER],
|
||||||
|
[AC_MSG_CHECKING([for $2 in -l$1 (order $3)])
|
||||||
|
dnl Use a cache variable name containing both the library and function name,
|
||||||
|
dnl because the test really is for library $1 defining function $2, not
|
||||||
|
dnl just for library $1. Separate tests with the same $1 and different $2s
|
||||||
|
dnl may have different results.
|
||||||
|
ac_lib_var=`echo $1['_']$2['_']$3 | sed 'y%./+-%__p_%'`
|
||||||
|
AC_CACHE_VAL(ac_cv_lib_$ac_lib_var,
|
||||||
|
[ac_save_LIBS="$LIBS"
|
||||||
|
LIBS="-l$1 $6 $LIBS"
|
||||||
|
AC_TRY_LINK(dnl
|
||||||
|
ifelse([AC_LANG], [FORTRAN77], ,
|
||||||
|
ifelse([$2], [main], , dnl Avoid conflicting decl of main.
|
||||||
|
[/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
|
]ifelse([AC_LANG], CPLUSPLUS, [#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
])dnl
|
||||||
|
[/* We use char because int might match the return type of a gcc2
|
||||||
|
builtin and then its argument prototype would still apply. */
|
||||||
|
char $2();
|
||||||
|
])),
|
||||||
|
[$2()],
|
||||||
|
eval "ac_cv_lib_$ac_lib_var=yes",
|
||||||
|
eval "ac_cv_lib_$ac_lib_var=no")
|
||||||
|
LIBS="$ac_save_LIBS"
|
||||||
|
])dnl
|
||||||
|
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
ifelse([$4], ,
|
||||||
|
[changequote(, )dnl
|
||||||
|
ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \
|
||||||
|
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
|
||||||
|
changequote([, ])dnl
|
||||||
|
AC_DEFINE_UNQUOTED($ac_tr_lib)
|
||||||
|
LIBS="-l$1 $LIBS"
|
||||||
|
], [$4])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
ifelse([$5], , , [$5
|
||||||
|
])dnl
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dnl Should we try and detect the GD libs?
|
||||||
|
if test x$TRYGD = xyep; then
|
||||||
|
|
||||||
|
dnl libiconv is required on some systems - tack it on if found
|
||||||
|
AC_CHECK_LIB(iconv,main,ICONV=-liconv,)
|
||||||
|
|
||||||
|
dnl See if the GD lib is available and supports PNG images...
|
||||||
|
|
||||||
|
dnl GD > 1.8.3 requires the TrueType library to be present as well, so test for that first...
|
||||||
|
JMD_CHECK_LIB_ORDER(gd,gdImagePng,1,[
|
||||||
|
GDLIBFOUND=yep
|
||||||
|
GDLIBS="-lgd -lttf -lpng -ljpeg -lz -lm"
|
||||||
|
],:,[-lttf -lpng -ljpeg -lz -lm])
|
||||||
|
|
||||||
|
dnl GD > 1.8.1 requires the jpeg library to be present as well, so test for that...
|
||||||
|
if test x$GDLIBFOUND = x; then
|
||||||
|
JMD_CHECK_LIB_ORDER(gd,gdImagePng,2,[
|
||||||
|
GDLIBFOUND=yep
|
||||||
|
GDLIBS="-lgd $ICONV -lpng -ljpeg -lz -lm"
|
||||||
|
],:,[$ICONV -lpng -ljpeg -lz -lm])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl If we failed the first test, try without jpeg library
|
||||||
|
if test x$GDLIBFOUND = x; then
|
||||||
|
JMD_CHECK_LIB_ORDER(gd,gdImagePng,3,[
|
||||||
|
GDLIBFOUND=yep
|
||||||
|
GDLIBS="-lgd $ICONV -lz -lm -lpng"
|
||||||
|
],:,[$ICONV -lz -lm -lpng])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl We failed again, so try a different library ordering (without jpeg libs)
|
||||||
|
if test x$GDLIBFOUND = x; then
|
||||||
|
JMD_CHECK_LIB_ORDER(gd,gdImagePng,4,[
|
||||||
|
GDLIBFOUND=yep
|
||||||
|
GDLIBS="-lgd $ICONV -lpng -lz -lm"
|
||||||
|
],:,[$ICONV -lpng -lz -lm])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Did we find the necessary GD libraries?
|
||||||
|
if test x$GDLIBFOUND = x; then
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "*** GD, PNG, and/or JPEG libraries could not be located... *********"
|
||||||
|
echo ""
|
||||||
|
echo "Boutell's GD library is required to compile the statusmap, trends"
|
||||||
|
echo "and histogram CGIs. Get it from http://www.boutell.com/gd/, compile"
|
||||||
|
echo "it, and use the --with-gd-lib and --with-gd-inc arguments to specify"
|
||||||
|
echo "the locations of the GD library and include files."
|
||||||
|
echo ""
|
||||||
|
echo "NOTE: In addition to the gd-devel library, you'll also need to make"
|
||||||
|
echo " sure you have the png-devel and jpeg-devel libraries installed"
|
||||||
|
echo " on your system."
|
||||||
|
echo ""
|
||||||
|
echo "NOTE: After you install the necessary libraries on your system:"
|
||||||
|
echo " 1. Make sure /etc/ld.so.conf has an entry for the directory in"
|
||||||
|
echo " which the GD, PNG, and JPEG libraries are installed."
|
||||||
|
echo " 2. Run 'ldconfig' to update the run-time linker options."
|
||||||
|
echo " 3. Run 'make clean' in the Nagios distribution to clean out"
|
||||||
|
echo " any old references to your previous compile."
|
||||||
|
echo " 4. Rerun the configure script."
|
||||||
|
echo ""
|
||||||
|
echo "NOTE: If you can't get the configure script to recognize the GD libs"
|
||||||
|
echo " on your system, get over it and move on to other things. The"
|
||||||
|
echo " CGIs that use the GD libs are just a small part of the entire"
|
||||||
|
echo " Nagios package. Get everything else working first and then"
|
||||||
|
echo " revisit the problem. Make sure to check the nagios-users"
|
||||||
|
echo " mailing list archives for possible solutions to GD library"
|
||||||
|
echo " problems when you resume your troubleshooting."
|
||||||
|
echo ""
|
||||||
|
echo "********************************************************************"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
dnl We found the GD lib!
|
||||||
|
else
|
||||||
|
echo "GD library was found!"
|
||||||
|
if test x$TRYSTATUSMAP = xyep; then
|
||||||
|
AC_DEFINE_UNQUOTED(USE_STATUSMAP,,[defined if the user chose to include status map])
|
||||||
|
CGIEXTRAS="$CGIEXTRAS statusmap.cgi"
|
||||||
|
AC_CHECK_LIB(gd,gdImageCreateTrueColor,
|
||||||
|
AC_DEFINE(HAVE_GDIMAGECREATETRUECOLOR,1,
|
||||||
|
[Define if your gd library has gdImageCreateTrueColor]))
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl compile trends CGI
|
||||||
|
AC_DEFINE_UNQUOTED(USE_TRENDS,,[compile trends CGI])
|
||||||
|
CGIEXTRAS="$CGIEXTRAS trends.cgi"
|
||||||
|
|
||||||
|
dnl compile histogram CGI
|
||||||
|
AC_DEFINE_UNQUOTED(USE_HISTOGRAM,,[compile histogram CGI])
|
||||||
|
CGIEXTRAS="$CGIEXTRAS histogram.cgi"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_WITH(cgiurl,--with-cgiurl=<local-url> sets URL for cgi programs (do not use a trailing slash),cgiurl=$withval,cgiurl=/nagios/cgi-bin)
|
||||||
|
AC_ARG_WITH(htmurl,--with-htmurl=<local-url> sets URL for public html,htmurl=$withval,htmurl=/nagios)
|
||||||
|
AC_SUBST(htmurl)
|
||||||
|
AC_SUBST(cgiurl)
|
||||||
|
|
||||||
|
USE_NANOSLEEP=yes
|
||||||
|
AC_ARG_ENABLE(nanosleep,--enable-nanosleep enables use of nanosleep (instead of sleep) in event timing,USE_NANOSLEEP=$enableval,USE_NANOSLEEP=yes)
|
||||||
|
if test x$USE_NANOSLEEP = xyes; then
|
||||||
|
AC_DEFINE_UNQUOTED(USE_NANOSLEEP,,[enables use of nanosleep (instead of sleep)])
|
||||||
|
fi
|
||||||
|
|
||||||
|
USE_EVENTBROKER=yes
|
||||||
|
AC_ARG_ENABLE(event-broker,--enable-event-broker enables integration of event broker routines,USE_EVENTBROKER=$enableval,USE_EVENTBROKER=yes)
|
||||||
|
|
||||||
|
BROKER_LDFLAGS=""
|
||||||
|
BROKERLIBS="";
|
||||||
|
some_dl_found="no";
|
||||||
|
if test x$USE_EVENTBROKER = xyes; then
|
||||||
|
|
||||||
|
dnl Which loader library should we use? libtdl or dl?
|
||||||
|
dnl Hopefully this will be portable and not give us headaches...
|
||||||
|
AC_CHECK_HEADER(ltdl.h,[
|
||||||
|
AC_CHECK_LIB(ltdl,lt_dlinit,[
|
||||||
|
AC_DEFINE(HAVE_LTDL_H,,[Which loader library should we use? libtdl or dl?])
|
||||||
|
some_dl_found="yes"
|
||||||
|
BROKERLIBS="$BROKERLIBS -lltdl"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
if test "x$some_dl_found" != xyes; then
|
||||||
|
AC_CHECK_HEADER(dlfcn.h,[
|
||||||
|
AC_CHECK_LIB(dl,dlopen,[
|
||||||
|
AC_DEFINE(HAVE_DLFCN_H,,[Which loader library should we use? libtdl or dl?])
|
||||||
|
some_dl_found="yes"
|
||||||
|
BROKERLIBS="$BROKERLIBS -ldl"
|
||||||
|
])
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl - Modified from www.erlang.org
|
||||||
|
# Check how to export functions from the broker executable, needed
|
||||||
|
# when dynamically loaded drivers are loaded (so that they can find
|
||||||
|
# broker functions).
|
||||||
|
# OS'es with ELF executables using the GNU linker (Linux and recent *BSD,
|
||||||
|
# in rare cases Solaris) typically need '-Wl,-export-dynamic' (i.e. pass
|
||||||
|
# -export-dynamic to the linker - also known as -rdynamic and some other
|
||||||
|
# variants); some sysVr4 system(s) instead need(s) '-Wl,-Bexport'.
|
||||||
|
# AIX 4.x (perhaps only for x>=2) wants -Wl,-bexpall,-brtl and doesn't
|
||||||
|
# reliably return an error for others, thus we separate it out.
|
||||||
|
# Otherwise we assume that if the linker accepts the flag, it is needed.
|
||||||
|
AC_MSG_CHECKING(for extra flags needed to export symbols)
|
||||||
|
case $host_os in
|
||||||
|
aix4*|aix5*)
|
||||||
|
BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-bexpall,-brtl"
|
||||||
|
;;
|
||||||
|
bsdi*)
|
||||||
|
BROKER_LDFLAGS="$BROKER_LDFLAGS -rdynamic"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
save_ldflags="$LDFLAGS"
|
||||||
|
LDFLAGS=-Wl,-export-dynamic
|
||||||
|
AC_TRY_LINK(,,[BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-export-dynamic"], [
|
||||||
|
LDFLAGS=-Wl,-Bexport
|
||||||
|
AC_TRY_LINK(,,[BROKER_LDFLAGS="$BROKER_LDFLAGS -Wl,-Bexport"],
|
||||||
|
AC_MSG_RESULT(none))])
|
||||||
|
LDFLAGS="$save_ldflags"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_SUBST(BROKER_LDFLAGS)
|
||||||
|
AC_SUBST(BROKERLIBS)
|
||||||
|
test "x$BROKER_LDFLAGS" != x && AC_MSG_RESULT([$BROKER_LDFLAGS])
|
||||||
|
|
||||||
|
|
||||||
|
dnl - Modified version from www.erlang.org
|
||||||
|
dnl - Some 12/15/05 mods made after reading http://xaxxon.slackworks.com/phuku/dl.html
|
||||||
|
AC_MSG_CHECKING(for linker flags for loadable modules)
|
||||||
|
case $host_os in
|
||||||
|
solaris2*|sysv4*)
|
||||||
|
MOD_LDFLAGS="-G"
|
||||||
|
;;
|
||||||
|
aix4*|aix5*)
|
||||||
|
#MOD_LDFLAGS="-G -bnoentry -bexpall"
|
||||||
|
MOD_LDFLAGS="-G -bM:SRE -bnoentry -bexpall"
|
||||||
|
;;
|
||||||
|
freebsd2*)
|
||||||
|
# Non-ELF GNU linker
|
||||||
|
MOD_LDFLAGS="-Bshareable"
|
||||||
|
;;
|
||||||
|
darwin*)
|
||||||
|
# Mach-O linker, a shared lib and a loadable
|
||||||
|
# object file is not the same thing.
|
||||||
|
MOD_LDFLAGS="-bundle -flat_namespace -undefined suppress"
|
||||||
|
MOD_CFLAGS="$MOD_CFLAGS -fno-common"
|
||||||
|
;;
|
||||||
|
linux* | k*bsd*-gnu*)
|
||||||
|
# assume GNU linker and ELF
|
||||||
|
MOD_LDFLAGS="-shared"
|
||||||
|
MOD_CFLAGS="-fPIC"
|
||||||
|
;;
|
||||||
|
freebsd*)
|
||||||
|
MOD_LDFLAGS="-shared"
|
||||||
|
MOD_CFLAGS="-fPIC"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# assume GNU linker and ELF
|
||||||
|
MOD_LDFLAGS="-shared"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_RESULT([$MOD_LDFLAGS])
|
||||||
|
AC_SUBST(MOD_CFLAGS)
|
||||||
|
AC_SUBST(MOD_LDFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
AC_DEFINE_UNQUOTED(USE_EVENT_BROKER,,[defined to bring in the event broker objects])
|
||||||
|
BROKER_O="broker.o nebmods.o"
|
||||||
|
AC_SUBST(BROKER_O)
|
||||||
|
BROKER_H="../include/broker.h ../include/nebmods.h ../include/nebmodules.h ../include/nebcallbacks.h ../include/neberrors.h"
|
||||||
|
AC_SUBST(BROKER_H)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
USEPERL=no;
|
||||||
|
INSTALLPERLSTUFF=no;
|
||||||
|
AC_ARG_ENABLE(embedded-perl,--enable-embedded-perl will enable embedded Perl interpreter,[
|
||||||
|
USEPERL=$enableval
|
||||||
|
]
|
||||||
|
,USEPERL=no)
|
||||||
|
|
||||||
|
PERLCACHE=yes;
|
||||||
|
AC_ARG_WITH(perlcache,--with-perlcache turns on cacheing of internally compiled Perl scripts,[
|
||||||
|
PERLCACHE=$withval
|
||||||
|
]
|
||||||
|
,[
|
||||||
|
AC_DEFINE(DO_CLEAN,"1",[whether to clean cached compiled perl])
|
||||||
|
PERLCACHE=yes;
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl Is embedded Perl being compiled in?
|
||||||
|
if test x$USEPERL = xyes; then
|
||||||
|
|
||||||
|
AC_DEFINE_UNQUOTED(EMBEDDEDPERL,,[Is embedded Perl being compiled in?])
|
||||||
|
PERLLIBS="`perl -MExtUtils::Embed -e ldopts`"
|
||||||
|
PERLDIR="`perl -MConfig -e 'print $Config{installsitearch}'`"
|
||||||
|
CFLAGS="${CFLAGS} `perl -MExtUtils::Embed -e ccopts`"
|
||||||
|
USEPERL=yes
|
||||||
|
INSTALLPERLSTUFF=yes;
|
||||||
|
PERLXSI_O=perlxsi.o
|
||||||
|
OBJS="${OBJS} ${PERLXSI_O}"
|
||||||
|
echo "creating base/perlxsi.c"
|
||||||
|
perl -MExtUtils::Embed -e xsinit -- -o base/perlxsi.c
|
||||||
|
|
||||||
|
echo "Embedded Perl interpreter will be compiled in..."
|
||||||
|
|
||||||
|
dnl Is caching enabled?
|
||||||
|
if test x$PERLCACHE = xyes; then
|
||||||
|
AC_DEFINE(DO_CLEAN,"0",[whether to clean cached compiled perl])
|
||||||
|
PERLCACHE=yes;
|
||||||
|
echo "Internally compiled Perl scripts will be cached..."
|
||||||
|
else
|
||||||
|
AC_DEFINE(DO_CLEAN,"1",[whether to clean cached compiled perl])
|
||||||
|
echo "Internally compiled Perl scripts will NOT be cached..."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Test if we're using threaded Perl (patch by Chip Ach)
|
||||||
|
if test x$USEPERL = xyes; then
|
||||||
|
if (perl -e 'use Config;exit -1 unless ($Config{'usethreads'});'); then
|
||||||
|
echo "Using threaded perl"
|
||||||
|
AC_DEFINE_UNQUOTED(THREADEDPERL,,[defined if we're using threaded Perl])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
dnl Option for compiling under CYGWIN
|
||||||
|
nagios_name=nagios
|
||||||
|
nagiostats_name=nagiostats
|
||||||
|
cygwin=no
|
||||||
|
AC_ARG_ENABLE(cygwin,--enable-cygwin enables building under the CYGWIN environment,[
|
||||||
|
cygwin=$enableval
|
||||||
|
])
|
||||||
|
if test x$cygwin = xyes; then
|
||||||
|
CFLAGS="${CFLAGS} -DCYGWIN"
|
||||||
|
nagios_name=nagios.exe;
|
||||||
|
nagiostats_name=nagiostats.exe;
|
||||||
|
fi
|
||||||
|
AC_SUBST(nagios_name)
|
||||||
|
AC_SUBST(nagiostats_name)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Should predictive failure routines be compiled in?
|
||||||
|
dnl AC_ARG_ENABLE(failure-prediction,--enable-failure-prediction will enable integration with failure prediction module (NOT HERE YET!),[
|
||||||
|
dnl AC_DEFINE_UNQUOTED(PREDICT_FAILURES)
|
||||||
|
dnl BASEEXTRALIBS="$BASEEXTRALIBS \$(FDATALIBS)"
|
||||||
|
dnl echo "Failure prediction routines (incomplete!) will be compiled in..."
|
||||||
|
dnl ])
|
||||||
|
|
||||||
|
dnl Find traceroute
|
||||||
|
AC_PATH_PROG(PATH_TO_TRACEROUTE,traceroute)
|
||||||
|
AC_DEFINE_UNQUOTED(TRACEROUTE_COMMAND,"$PATH_TO_TRACEROUTE",[traceroute command to use])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dnl Package directory for Solaris pkgmk (and other OSs, eventually)
|
||||||
|
dnl VERSION=`grep 1.0 include/common.h | cut -d ' ' -f 3 | sed 's/"//g'`
|
||||||
|
VERSION=$PKG_VERSION
|
||||||
|
PACKDIR=`pwd`/pkg
|
||||||
|
AC_SUBST(PACKDIR)
|
||||||
|
AC_SUBST(VERSION)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(for type va_list)
|
||||||
|
AC_TRY_COMPILE([#ifdef __STDC__
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <varargs.h>
|
||||||
|
#endif],
|
||||||
|
[va_list args;],
|
||||||
|
[AC_MSG_RESULT(yes)],
|
||||||
|
[AC_DEFINE(NEED_VA_LIST,,[defined if va_list fails to compile]) AC_MSG_RESULT(no)])
|
||||||
|
|
||||||
|
dnl Check if we should build local libtap
|
||||||
|
dnl From Nagios Plugins
|
||||||
|
dnl Have disabled autodetection of system library until later
|
||||||
|
AC_ARG_ENABLE(libtap,
|
||||||
|
AC_HELP_STRING([--enable-libtap],
|
||||||
|
[Enable built-in libtap for unit-testing (default: no).]),
|
||||||
|
[enable_libtap=$enableval],
|
||||||
|
[enable_libtap=no])
|
||||||
|
#Disabled for moment
|
||||||
|
#AM_CONDITIONAL([USE_LIBTAP_LOCAL],[test "$enable_libtap" = "yes"])
|
||||||
|
|
||||||
|
# Disabled for moment
|
||||||
|
# If not local, check if we can use the system one
|
||||||
|
#if test "$enable_libtap" != "yes" ; then
|
||||||
|
# dnl Check for libtap, to run perl-like tests
|
||||||
|
# AC_CHECK_LIB(tap, plan_tests,
|
||||||
|
# enable_libtap="yes"
|
||||||
|
# )
|
||||||
|
#fi
|
||||||
|
|
||||||
|
# Finally, define tests if we use libtap
|
||||||
|
if test "$enable_libtap" = "yes" ; then
|
||||||
|
AC_CONFIG_SUBDIRS([tap])
|
||||||
|
USE_LIBTAP=yes
|
||||||
|
else
|
||||||
|
USE_LIBTAP=no
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
AC_SUBST(USE_LIBTAP)
|
||||||
|
AC_SUBST(CGIEXTRAS)
|
||||||
|
AC_SUBST(GDLIBS)
|
||||||
|
AC_SUBST(PERLLIBS)
|
||||||
|
AC_SUBST(PERLDIR)
|
||||||
|
AC_SUBST(PERLXSI_O)
|
||||||
|
AC_SUBST(BASEEXTRALIBS)
|
||||||
|
AC_SUBST(INITDIR)
|
||||||
|
AC_SUBST(INSTALLPERLSTUFF)
|
||||||
|
AC_SUBST(USE_EVENTBROKER)
|
||||||
|
|
||||||
|
AC_PATH_PROG(PERL,perl)
|
||||||
|
|
||||||
|
AC_OUTPUT(Makefile subst pkginfo base/Makefile common/Makefile contrib/Makefile cgi/Makefile html/Makefile module/Makefile xdata/Makefile daemon-init t/Makefile t-tap/Makefile)
|
||||||
|
|
||||||
|
|
||||||
|
perl subst include/locations.h
|
||||||
|
perl subst html/config.inc.php
|
||||||
|
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Creating sample config files in sample-config/ ..."
|
||||||
|
|
||||||
|
perl subst sample-config/nagios.cfg
|
||||||
|
perl subst sample-config/cgi.cfg
|
||||||
|
perl subst sample-config/resource.cfg
|
||||||
|
perl subst sample-config/httpd.conf
|
||||||
|
perl subst sample-config/mrtg.cfg
|
||||||
|
|
||||||
|
perl subst sample-config/template-object/templates.cfg
|
||||||
|
perl subst sample-config/template-object/commands.cfg
|
||||||
|
perl subst sample-config/template-object/timeperiods.cfg
|
||||||
|
perl subst sample-config/template-object/contacts.cfg
|
||||||
|
|
||||||
|
perl subst sample-config/template-object/localhost.cfg
|
||||||
|
perl subst sample-config/template-object/windows.cfg
|
||||||
|
perl subst sample-config/template-object/printer.cfg
|
||||||
|
perl subst sample-config/template-object/switch.cfg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dnl Review options
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
AC_MSG_RESULT([*** Configuration summary for $PKG_NAME $PKG_VERSION $PKG_REL_DATE ***:])
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " General Options:"
|
||||||
|
echo " -------------------------"
|
||||||
|
|
||||||
|
AC_MSG_RESULT([ Nagios executable: $nagios_name])
|
||||||
|
AC_MSG_RESULT([ Nagios user/group: $nagios_user,$nagios_grp])
|
||||||
|
AC_MSG_RESULT([ Command user/group: $command_user,$command_grp])
|
||||||
|
if test x$USEPERL = xyes; then
|
||||||
|
if test x$PERLCACHE = xyes; then
|
||||||
|
AC_MSG_RESULT([ Embedded Perl: yes, with caching])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([ Embedded Perl: yes, without caching])
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([ Embedded Perl: no])
|
||||||
|
fi
|
||||||
|
if test x$USE_EVENTBROKER = xyes; then
|
||||||
|
AC_MSG_RESULT([ Event Broker: yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([ Event Broker: no])
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([ Install \${prefix}: $prefix])
|
||||||
|
AC_MSG_RESULT([ Lock file: $lockfile])
|
||||||
|
AC_MSG_RESULT([ Check result directory: $CHECKRESULTDIR])
|
||||||
|
AC_MSG_RESULT([ Init directory: $init_dir])
|
||||||
|
AC_MSG_RESULT([ Apache conf.d directory: $HTTPD_CONF])
|
||||||
|
AC_MSG_RESULT([ Mail program: $MAIL_PROG])
|
||||||
|
AC_MSG_RESULT([ Host OS: $host_os])
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " Web Interface Options:"
|
||||||
|
echo " ------------------------"
|
||||||
|
|
||||||
|
AC_MSG_RESULT([ HTML URL: http://localhost$htmurl/])
|
||||||
|
AC_MSG_RESULT([ CGI URL: http://localhost$cgiurl/])
|
||||||
|
AC_MSG_RESULT([ Traceroute (used by WAP): $PATH_TO_TRACEROUTE])
|
||||||
|
|
||||||
|
dnl echo ""
|
||||||
|
dnl echo " External Data Routines:"
|
||||||
|
dnl echo " ------------------------"
|
||||||
|
|
||||||
|
dnl AC_MSG_RESULT([ Status data: $XSDCOMMENT])
|
||||||
|
dnl AC_MSG_RESULT([ Comment data: $XCDCOMMENT])
|
||||||
|
dnl AC_MSG_RESULT([ Downtime data: $XDDCOMMENT])
|
||||||
|
dnl AC_MSG_RESULT([ Peformance data: $XPDCOMMENT])
|
||||||
|
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "Review the options above for accuracy. If they look okay,"
|
||||||
|
echo "type 'make all' to compile the main program and CGIs."
|
||||||
|
echo ""
|
||||||
|
|
2
contrib/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
perlxsi.c
|
||||||
|
Makefile
|
90
contrib/Makefile.in
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
###############################
|
||||||
|
# Makefile for contrib software
|
||||||
|
#
|
||||||
|
# Last Modified: 05-19-2008
|
||||||
|
###############################
|
||||||
|
|
||||||
|
CC=@CC@
|
||||||
|
CFLAGS=@CFLAGS@ @DEFS@
|
||||||
|
LDFLAGS=@LDFLAGS@ @LIBS@
|
||||||
|
|
||||||
|
# Source code directories
|
||||||
|
SRC_INCLUDE=../include
|
||||||
|
SRC_COMMON=../common
|
||||||
|
SRC_CGI=../cgi
|
||||||
|
|
||||||
|
# Generated automatically from configure script
|
||||||
|
SNPRINTF_O=@SNPRINTF_O@
|
||||||
|
INSTALL=@INSTALL@
|
||||||
|
INSTALL_OPTS=@INSTALL_OPTS@
|
||||||
|
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
CGIDIR=@sbindir@
|
||||||
|
BINDIR=@bindir@
|
||||||
|
|
||||||
|
CGIS=traceroute.cgi daemonchk.cgi
|
||||||
|
UTILS=mini_epn new_mini_epn convertcfg
|
||||||
|
ALL=$(CGIS) $(UTILS)
|
||||||
|
|
||||||
|
|
||||||
|
CGI_C=$(SRC_CGI)/getcgi.c
|
||||||
|
CGI_O=$(SRC_CGI)/getcgi.o $(SNPRINTF_O)
|
||||||
|
CGI_H=$(SRC_INCLUDE)/getcgi.h
|
||||||
|
COMMON_H=$(SRC_INCLUDE)/config.h $(SRC_INCLUDE)/common.h $(SRC_INCLUDE)/locations.h
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# standard targets (all, clean, distclean, devclean, install)
|
||||||
|
|
||||||
|
all: $(ALL)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f convertcfg daemonchk.cgi mini_epn new_mini_epn core *.o
|
||||||
|
rm -f */*/*~
|
||||||
|
rm -f */*~
|
||||||
|
rm -f *~
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile
|
||||||
|
|
||||||
|
devclean: distclean
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(CGIDIR)
|
||||||
|
$(INSTALL) -m 775 $(INSTALL_OPTS) -d $(DESTDIR)$(BINDIR)
|
||||||
|
for f in $(CGIS); do $(INSTALL) -m 775 $(INSTALL_OPTS) $$f $(DESTDIR)$(CGIDIR); done
|
||||||
|
for f in $(UTILS); do $(INSTALL) -m 775 $(INSTALL_OPTS) $$f $(DESTDIR)$(BINDIR); done
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# rules and dependencies for actual target programs
|
||||||
|
|
||||||
|
daemonchk.cgi: daemonchk.o $(CGI_O) $(CGI_H) $(COMMON_H)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(CGI_O)
|
||||||
|
|
||||||
|
daemonchk.o: daemonchk.c
|
||||||
|
$(CC) $(CLFAGS) -c -o $@ $< -I$(SRC_INCLUDE)
|
||||||
|
|
||||||
|
mini_epn: mini_epn.c
|
||||||
|
perl -MExtUtils::Embed -e xsinit
|
||||||
|
$(CC) $(CFLAGS) -c perlxsi.c `perl -MExtUtils::Embed -e ccopts`
|
||||||
|
$(CC) $(CFLAGS) -c mini_epn.c `perl -MExtUtils::Embed -e ccopts`
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) perlxsi.o mini_epn.o `perl -MExtUtils::Embed -e ccopts -e ldopts` -o $@
|
||||||
|
|
||||||
|
new_mini_epn: new_mini_epn.c
|
||||||
|
perl -MExtUtils::Embed -e xsinit
|
||||||
|
$(CC) $(CFLAGS) -c perlxsi.c `perl -MExtUtils::Embed -e ccopts`
|
||||||
|
$(CC) $(CFLAGS) -c new_mini_epn.c `perl -MExtUtils::Embed -e ccopts`
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) perlxsi.o new_mini_epn.o `perl -MExtUtils::Embed -e ccopts -e ldopts` -o $@
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# dependencies
|
||||||
|
|
||||||
|
$(CGI_O): $(CGI_C)
|
||||||
|
cd $(SRC_CGI) && make $(CGI_O)
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# implicit rules
|
||||||
|
|
||||||
|
%.cgi : %.c
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) $< $(CGI_O) -o $@
|
48
contrib/README
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#####################
|
||||||
|
Nagios Contrib README
|
||||||
|
#####################
|
||||||
|
|
||||||
|
This directory contains various programs, scripts, etc. that
|
||||||
|
have been contribed by various people. Read the source code
|
||||||
|
if you want to find who did what.
|
||||||
|
|
||||||
|
Here is a description of what you'll find...
|
||||||
|
|
||||||
|
|
||||||
|
Conversion Programs:
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
- convertcfg.c is a program to quickly convert old "host" config
|
||||||
|
files to the new template-based object config files. It can also
|
||||||
|
convert extended host information definitions. Type 'make convertcfg'
|
||||||
|
to compile the utility.
|
||||||
|
|
||||||
|
|
||||||
|
Additional CGIs:
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- traceroute.cgi is (surprise) a CGI that allows you to do a traceroute
|
||||||
|
to a specific IP address. Simply do a 'chmod +x' to make it executeable
|
||||||
|
and place it in the CGI directory (i.e. /usr/local/nagios/sbin).
|
||||||
|
Requires Perl.
|
||||||
|
|
||||||
|
- daemonchk.c is a CGI contributed by Karl DeBisschop that can test to
|
||||||
|
see whether or not the Nagios process is running.
|
||||||
|
|
||||||
|
|
||||||
|
Miscellaneous Goodies:
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
- htaccess.sample is a *sample* .htaccess file that can be used with
|
||||||
|
Apache to require password authentication for access to the web
|
||||||
|
interface.
|
||||||
|
|
||||||
|
- mini_epn.c is a mini embedded Perl interpreter that can be used to
|
||||||
|
test the feasibility of running various Perl plugins with the
|
||||||
|
embedded Perl interpreter compiled in.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
747
contrib/convertcfg.c
Normal file
@ -0,0 +1,747 @@
|
|||||||
|
/************************************************************************
|
||||||
|
*
|
||||||
|
* CONVERTCFG.C - Config File Convertor
|
||||||
|
*
|
||||||
|
* Copyright (c) 2001-2005 Ethan Galstad (egalstad@nagios.org)
|
||||||
|
* Last Modified: 08-12-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.
|
||||||
|
*
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char *my_strsep(char **, const char *);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
FILE *fp;
|
||||||
|
char *temp_ptr;
|
||||||
|
char *temp_ptr2;
|
||||||
|
char input[8096];
|
||||||
|
int notify_recovery;
|
||||||
|
int notify_warning;
|
||||||
|
int notify_critical;
|
||||||
|
int notify_down;
|
||||||
|
int notify_unreachable;
|
||||||
|
int option;
|
||||||
|
int have_template = 0;
|
||||||
|
int x = 0, y = 0;
|
||||||
|
char *host_name;
|
||||||
|
char *service_description;
|
||||||
|
char *host_name2;
|
||||||
|
char *service_description2;
|
||||||
|
|
||||||
|
if(argc != 3) {
|
||||||
|
printf("Nagios Config File Converter\n");
|
||||||
|
printf("Written by Ethan Galstad (egalstad@nagios.org)\n");
|
||||||
|
printf("Last Modified: 08-12-2005\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Usage: %s <config file> <object type>\n", argv[0]);
|
||||||
|
printf("\n");
|
||||||
|
printf("Valid object types include:\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("\ttimeperiods\n");
|
||||||
|
printf("\tcommands\n");
|
||||||
|
printf("\tcontacts\n");
|
||||||
|
printf("\tcontactgroups\n");
|
||||||
|
printf("\thosts\n");
|
||||||
|
printf("\thostgroups\n");
|
||||||
|
printf("\thostgroupescalationss\n");
|
||||||
|
printf("\tservices\n");
|
||||||
|
printf("\tservicedependencies\n");
|
||||||
|
printf("\tserviceescalations\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("\thostextinfo\n");
|
||||||
|
printf("\tserviceextinfo\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Notes:\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("This utility is designed to aide you in converting your old 'host'\n");
|
||||||
|
printf("config file(s) to the new template-based config file style. It is\n");
|
||||||
|
printf("also capable of converting extended host and service information\n");
|
||||||
|
printf("definitions in your old CGI config file.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Supply the name of your old 'host' config file (or your old CGI config\n");
|
||||||
|
printf("file if you're converting extended host/service definitions) on the\n");
|
||||||
|
printf("command line, along with the type of object you would like to produce\n");
|
||||||
|
printf("a new config file for. Your old config file is not overwritten - new\n");
|
||||||
|
printf("configuration data is printed to standard output, so you can redirect it\n");
|
||||||
|
printf("wherever you like.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Please note that you can only specify one type of object at a time\n");
|
||||||
|
printf("on the command line.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("IMPORTANT: This utility will generate Nagios 1.x compliant config files.\n");
|
||||||
|
printf("However, the config files are not totally compatible with Nagios 2.x, so\n");
|
||||||
|
printf("you will have to do some manual tweaking.\n");
|
||||||
|
printf("\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fp = fopen(argv[1], "r");
|
||||||
|
if(fp == NULL) {
|
||||||
|
printf("Error: Could not open file '%s' for reading.\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(fgets(input, sizeof(input) - 1, fp); !feof(fp); fgets(input, sizeof(input) - 1, fp)) {
|
||||||
|
|
||||||
|
/* skip blank lines and comments */
|
||||||
|
if(input[0] == '#' || input[0] == '\x0' || input[0] == '\n' || input[0] == '\r')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* timeperiods */
|
||||||
|
if(strstr(input, "timeperiod[") && !strcmp(argv[2], "timeperiods")) {
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "]");
|
||||||
|
|
||||||
|
printf("# '%s' timeperiod definition\n", temp_ptr);
|
||||||
|
printf("define timeperiod{\n");
|
||||||
|
/*printf("\tname\t\t%s\n",temp_ptr);*/
|
||||||
|
printf("\ttimeperiod_name\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\talias\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tsunday\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tmonday\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\ttuesday\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\twednesday\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tthursday\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tfriday\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tsaturday\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* commands */
|
||||||
|
if(strstr(input, "command[") && !strcmp(argv[2], "commands")) {
|
||||||
|
|
||||||
|
temp_ptr = strtok(input, "[");
|
||||||
|
temp_ptr = strtok(NULL, "]");
|
||||||
|
|
||||||
|
printf("# '%s' command definition\n", temp_ptr);
|
||||||
|
printf("define command{\n");
|
||||||
|
/*printf("\tname\t\t%s\n",temp_ptr);*/
|
||||||
|
printf("\tcommand_name\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = strtok(NULL, "\n");
|
||||||
|
|
||||||
|
printf("\tcommand_line\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* contacts */
|
||||||
|
if(strstr(input, "contact[") && !strcmp(argv[2], "contacts")) {
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "]");
|
||||||
|
|
||||||
|
printf("# '%s' contact definition\n", temp_ptr);
|
||||||
|
printf("define contact{\n");
|
||||||
|
/*printf("\tname\t\t\t\t%s\n",temp_ptr);*/
|
||||||
|
printf("\tcontact_name\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\talias\t\t\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tservice_notification_period\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\thost_notification_period\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_recovery = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_critical = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_warning = atoi(temp_ptr);
|
||||||
|
|
||||||
|
option = 0;
|
||||||
|
printf("\tservice_notification_options\t");
|
||||||
|
if(notify_recovery == 1 || notify_critical == 1 || notify_warning == 1) {
|
||||||
|
if(notify_warning == 1) {
|
||||||
|
printf("w,u");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_critical == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("c");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_recovery == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("r");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_recovery = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_down = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_unreachable = atoi(temp_ptr);
|
||||||
|
|
||||||
|
option = 0;
|
||||||
|
printf("\thost_notification_options\t");
|
||||||
|
if(notify_recovery == 1 || notify_down == 1 || notify_unreachable == 1) {
|
||||||
|
if(notify_down == 1) {
|
||||||
|
printf("d");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_unreachable == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("u");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_recovery == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("r");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tservice_notification_commands\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\thost_notification_commands\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\temail\t\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tpager\t\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* contactgroups */
|
||||||
|
if(strstr(input, "contactgroup[") && !strcmp(argv[2], "contactgroups")) {
|
||||||
|
|
||||||
|
temp_ptr = strtok(input, "[");
|
||||||
|
temp_ptr = strtok(NULL, "]");
|
||||||
|
|
||||||
|
printf("# '%s' contact group definition\n", temp_ptr);
|
||||||
|
printf("define contactgroup{\n");
|
||||||
|
/*printf("\tname\t\t\t%s\n",temp_ptr);*/
|
||||||
|
printf("\tcontactgroup_name\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = strtok(NULL, ";");
|
||||||
|
printf("\talias\t\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = strtok(NULL, "\n");
|
||||||
|
|
||||||
|
printf("\tmembers\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hosts */
|
||||||
|
if(strstr(input, "host[") && !strcmp(argv[2], "hosts")) {
|
||||||
|
|
||||||
|
if(have_template == 0) {
|
||||||
|
|
||||||
|
printf("# Generic host definition template\n");
|
||||||
|
printf("define host{\n");
|
||||||
|
printf("\tname\t\t\t\tgeneric-host\t; The name of this host template - referenced in other host definitions, used for template recursion/resolution\n");
|
||||||
|
printf("\tactive_checks_enabled\t\t1\t; Active host checks are enabled\n");
|
||||||
|
printf("\tpassive_checks_enabled\t\t1\t; Passive host checks are enabled/accepted\n");
|
||||||
|
printf("\tnotifications_enabled\t\t1\t; Host notifications are enabled\n");
|
||||||
|
printf("\tevent_handler_enabled\t\t1\t; Host event handler is enabled\n");
|
||||||
|
printf("\tflap_detection_enabled\t\t1\t; Flap detection is enabled\n");
|
||||||
|
/*printf("\tfailure_prediction_enabled\t1\t; Failure prediction is enabled\n");*/
|
||||||
|
printf("\tprocess_perf_data\t\t1\t; Process performance data\n");
|
||||||
|
printf("\tretain_status_information\t1\t; Retain status information across program restarts\n");
|
||||||
|
printf("\tretain_nonstatus_information\t1\t; Retain non-status information across program restarts\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("\tregister\t\t\t0\t; DONT REGISTER THIS DEFINITION - ITS NOT A REAL HOST, JUST A TEMPLATE!\n");
|
||||||
|
printf("\t}\n\n");
|
||||||
|
|
||||||
|
have_template = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "]");
|
||||||
|
|
||||||
|
printf("# '%s' host definition\n", temp_ptr);
|
||||||
|
printf("define host{\n");
|
||||||
|
printf("\tuse\t\t\tgeneric-host\t\t; Name of host template to use\n\n");
|
||||||
|
printf("\thost_name\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\talias\t\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\taddress\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tparents\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tcheck_command\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tmax_check_attempts\t%d\n", atoi(temp_ptr));
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tnotification_interval\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tnotification_period\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_recovery = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_down = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_unreachable = atoi(temp_ptr);
|
||||||
|
|
||||||
|
option = 0;
|
||||||
|
printf("\tnotification_options\t");
|
||||||
|
if(notify_recovery == 1 || notify_down == 1 || notify_unreachable == 1) {
|
||||||
|
if(notify_down == 1) {
|
||||||
|
printf("d");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_unreachable == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("u");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_recovery == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("r");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tevent_handler\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hostgroups */
|
||||||
|
if(strstr(input, "hostgroup[") && !strcmp(argv[2], "hostgroups")) {
|
||||||
|
|
||||||
|
temp_ptr = strtok(input, "[");
|
||||||
|
temp_ptr = strtok(NULL, "]");
|
||||||
|
|
||||||
|
printf("# '%s' host group definition\n", temp_ptr);
|
||||||
|
printf("define hostgroup{\n");
|
||||||
|
/*printf("\tname\t\t%s\n",temp_ptr);*/
|
||||||
|
printf("\thostgroup_name\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = strtok(NULL, ";");
|
||||||
|
printf("\talias\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = strtok(NULL, ";");
|
||||||
|
/*printf("\tcontact_groups\t%s\n",temp_ptr);*/
|
||||||
|
|
||||||
|
temp_ptr = strtok(NULL, "\n");
|
||||||
|
|
||||||
|
printf("\tmembers\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* services */
|
||||||
|
if(strstr(input, "service[") && !strcmp(argv[2], "services")) {
|
||||||
|
|
||||||
|
if(have_template == 0) {
|
||||||
|
|
||||||
|
printf("# Generic service definition template\n");
|
||||||
|
printf("define service{\n");
|
||||||
|
printf("\tname\t\t\t\tgeneric-service\t; The 'name' of this service template, referenced in other service definitions\n");
|
||||||
|
printf("\tactive_checks_enabled\t\t1\t; Active service checks are enabled\n");
|
||||||
|
printf("\tpassive_checks_enabled\t\t1\t; Passive service checks are enabled/accepted\n");
|
||||||
|
printf("\tparallelize_check\t\t1\t; Active service checks should be parallelized (disabling this can lead to major performance problems)\n");
|
||||||
|
printf("\tobsess_over_service\t\t1\t; We should obsess over this service (if necessary)\n");
|
||||||
|
printf("\tcheck_freshness\t\t\t0\t; Default is to NOT check service 'freshness'\n");
|
||||||
|
printf("\tnotifications_enabled\t\t1\t; Service notifications are enabled\n");
|
||||||
|
printf("\tevent_handler_enabled\t\t1\t; Service event handler is enabled\n");
|
||||||
|
printf("\tflap_detection_enabled\t\t1\t; Flap detection is enabled\n");
|
||||||
|
/*printf("\tfailure_prediction_enabled\t1\t; Failure prediction is enabled\n");*/
|
||||||
|
printf("\tprocess_perf_data\t\t1\t; Process performance data\n");
|
||||||
|
printf("\tretain_status_information\t1\t; Retain status information across program restarts\n");
|
||||||
|
printf("\tretain_nonstatus_information\t1\t; Retain non-status information across program restarts\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("\tregister\t\t\t0\t; DONT REGISTER THIS DEFINITION - ITS NOT A REAL SERVICE, JUST A TEMPLATE!\n");
|
||||||
|
printf("\t}\n\n");
|
||||||
|
|
||||||
|
have_template = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "]");
|
||||||
|
|
||||||
|
printf("# Service definition\n");
|
||||||
|
printf("define service{\n");
|
||||||
|
printf("\tuse\t\t\t\tgeneric-service\t\t; Name of service template to use\n\n");
|
||||||
|
printf("\thost_name\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tservice_description\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tis_volatile\t\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tcheck_period\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tmax_check_attempts\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tnormal_check_interval\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tretry_check_interval\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tcontact_groups\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tnotification_interval\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tnotification_period\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_recovery = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_critical = atoi(temp_ptr);
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
notify_warning = atoi(temp_ptr);
|
||||||
|
|
||||||
|
option = 0;
|
||||||
|
printf("\tnotification_options\t\t");
|
||||||
|
if(notify_recovery == 1 || notify_critical == 1 || notify_warning == 1) {
|
||||||
|
if(notify_warning == 1) {
|
||||||
|
printf("w,u");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_critical == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("c");
|
||||||
|
option = 1;
|
||||||
|
}
|
||||||
|
if(notify_recovery == 1) {
|
||||||
|
if(option == 1)
|
||||||
|
printf(",");
|
||||||
|
printf("r");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("n");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tevent_handler\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tcheck_command\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hostgroup escalations */
|
||||||
|
if(strstr(input, "hostgroupescalation[") && !strcmp(argv[2], "hostgroupescalations")) {
|
||||||
|
|
||||||
|
x++;
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "]");
|
||||||
|
|
||||||
|
printf("# Hostgroup '%s' escalation definition\n", temp_ptr);
|
||||||
|
printf("define hostgroupescalation{\n");
|
||||||
|
|
||||||
|
printf("\thostgroup_name\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "-");
|
||||||
|
printf("\tfirst_notification\t\t%d\n", atoi(temp_ptr + 1));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tlast_notification\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tcontact_groups\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
printf("\tnotification_interval\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* service escalations */
|
||||||
|
if(strstr(input, "serviceescalation[") && !strcmp(argv[2], "serviceescalations")) {
|
||||||
|
|
||||||
|
x++;
|
||||||
|
|
||||||
|
printf("# Serviceescalation definition\n");
|
||||||
|
printf("define serviceescalation{\n");
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
host_name = my_strsep(&temp_ptr2, ";");
|
||||||
|
service_description = my_strsep(&temp_ptr2, "]");
|
||||||
|
|
||||||
|
printf("\thost_name\t\t%s\n", host_name);
|
||||||
|
printf("\tservice_description\t\t%s\n", service_description);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "-");
|
||||||
|
printf("\tfirst_notification\t\t%d\n", atoi(temp_ptr + 1));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tlast_notification\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
printf("\tcontact_groups\t\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
printf("\tnotification_interval\t\t%d\n", atoi(temp_ptr));
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* service dependencies */
|
||||||
|
if(strstr(input, "servicedependency[") && !strcmp(argv[2], "servicedependencies")) {
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
host_name = my_strsep(&temp_ptr2, ";");
|
||||||
|
service_description = my_strsep(&temp_ptr2, "]");
|
||||||
|
host_name2 = my_strsep(&temp_ptr2, ";") + 1;
|
||||||
|
service_description2 = my_strsep(&temp_ptr2, ";");
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
|
||||||
|
x++;
|
||||||
|
|
||||||
|
printf("# Servicedependency definition\n");
|
||||||
|
printf("define servicedependency{\n");
|
||||||
|
|
||||||
|
printf("\thost_name\t\t\t%s\n", host_name2);
|
||||||
|
printf("\tservice_description\t\t%s\n", service_description2);
|
||||||
|
printf("\tdependent_host_name\t\t%s\n", host_name);
|
||||||
|
printf("\tdependent_service_description\t%s\n", service_description);
|
||||||
|
|
||||||
|
printf("\texecution_failure_criteria\t");
|
||||||
|
for(y = 0; temp_ptr[y] != '\x0'; y++)
|
||||||
|
printf("%s%c", (y > 0) ? "," : "", temp_ptr[y]);
|
||||||
|
if(y == 0)
|
||||||
|
printf("n");
|
||||||
|
printf("\t; These are the criteria for which check execution will be suppressed\n");
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
|
||||||
|
printf("\tnotification_failure_criteria\t");
|
||||||
|
for(y = 0; temp_ptr[y] != '\x0'; y++)
|
||||||
|
printf("%s%c", (y > 0) ? "," : "", temp_ptr[y]);
|
||||||
|
if(y == 0)
|
||||||
|
printf("n");
|
||||||
|
printf("\t; These are the criteria for which notifications will be suppressed\n");
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* extended host info */
|
||||||
|
if(strstr(input, "hostextinfo[") && !strcmp(argv[2], "hostextinfo")) {
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "]");
|
||||||
|
|
||||||
|
printf("# '%s' hostextinfo definition\n", temp_ptr);
|
||||||
|
printf("define hostextinfo{\n");
|
||||||
|
printf("\thost_name\t\t%s\t\t; The name of the host this data is associated with\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
|
||||||
|
if(temp_ptr + 1 != NULL && strcmp(temp_ptr + 1, ""))
|
||||||
|
printf("\tnotes_url\t\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\ticon_image\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tvrml_image\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\tstatusmap_image\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\ticon_image_alt\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\t2d_coords\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\t3d_coords\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* extended service info */
|
||||||
|
if(strstr(input, "serviceextinfo[") && !strcmp(argv[2], "serviceextinfo")) {
|
||||||
|
|
||||||
|
temp_ptr2 = &input[0];
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "[");
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
|
||||||
|
printf("# serviceextinfo definition\n", temp_ptr);
|
||||||
|
printf("define serviceextinfo{\n");
|
||||||
|
printf("\thost_name\t\t%s\t\t; The name of the service this data is associated with\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, "]");
|
||||||
|
printf("\tservice_description\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
|
||||||
|
if(temp_ptr + 1 != NULL && strcmp(temp_ptr + 1, ""))
|
||||||
|
printf("\tnotes_url\t\t%s\n", temp_ptr + 1);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\ticon_image\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
temp_ptr = my_strsep(&temp_ptr2, ";\r\n");
|
||||||
|
if(temp_ptr != NULL && strcmp(temp_ptr, ""))
|
||||||
|
printf("\ticon_image_alt\t\t%s\n", temp_ptr);
|
||||||
|
|
||||||
|
printf("\t}\n\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* fixes compiler problems under Solaris, since strsep() isn't included */
|
||||||
|
/* this code is taken from the glibc source */
|
||||||
|
char *my_strsep(char **stringp, const char *delim) {
|
||||||
|
char *begin, *end;
|
||||||
|
|
||||||
|
begin = *stringp;
|
||||||
|
if(begin == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* A frequent case is when the delimiter string contains only one
|
||||||
|
character. Here we don't need to call the expensive `strpbrk'
|
||||||
|
function and instead work using `strchr'. */
|
||||||
|
if(delim[0] == '\0' || delim[1] == '\0') {
|
||||||
|
char ch = delim[0];
|
||||||
|
|
||||||
|
if(ch == '\0')
|
||||||
|
end = NULL;
|
||||||
|
else {
|
||||||
|
if(*begin == ch)
|
||||||
|
end = begin;
|
||||||
|
else
|
||||||
|
end = strchr(begin + 1, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
/* Find the end of the token. */
|
||||||
|
end = strpbrk(begin, delim);
|
||||||
|
|
||||||
|
if(end) {
|
||||||
|
|
||||||
|
/* Terminate the token and set *STRINGP past NUL character. */
|
||||||
|
*end++ = '\0';
|
||||||
|
*stringp = end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* No more delimiters; this is the last token. */
|
||||||
|
*stringp = NULL;
|
||||||
|
|
||||||
|
return begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
277
contrib/daemonchk.c
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
#include "config.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "locations.h"
|
||||||
|
#include "cgiutils.h"
|
||||||
|
#include "getcgi.h"
|
||||||
|
#ifdef HAVE_GETOPT_H
|
||||||
|
#include <getopt.h>
|
||||||
|
#endif
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define CHARLEN 256
|
||||||
|
#define max(a,b) ((a)>(b))?(a):(b)
|
||||||
|
|
||||||
|
static void document_header(void);
|
||||||
|
//static void document_footer(void);
|
||||||
|
static int process_cgivars(void);
|
||||||
|
|
||||||
|
static char *strscpy(char *dest, const char *src);
|
||||||
|
static char *ssprintf(char *str, const char *fmt, ...);
|
||||||
|
static void terminate(int result, const char *fmt, ...);
|
||||||
|
static void get_expire_time_string(time_t *raw_time, char *buffer, int buffer_length);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
FILE *fp;
|
||||||
|
char *status_file = NULL;
|
||||||
|
char *lock_file = NULL;
|
||||||
|
char *proc_file = NULL;
|
||||||
|
char input_buffer[CHARLEN];
|
||||||
|
int c, age, pid, testpid, found;
|
||||||
|
int wt = -1;
|
||||||
|
int ct = -1;
|
||||||
|
struct stat statbuf;
|
||||||
|
time_t current_time;
|
||||||
|
|
||||||
|
#ifdef DEFAULT_STATUS_FILE
|
||||||
|
status_file = strscpy(status_file, DEFAULT_STATUS_FILE);
|
||||||
|
#else
|
||||||
|
status_file = strscpy(status_file, "/var/log/nagios/status.log");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEFAULT_LOCK_FILE
|
||||||
|
lock_file = strscpy(lock_file, DEFAULT_LOCK_FILE);
|
||||||
|
#else
|
||||||
|
lock_file = strscpy(lock_file, "/tmp/nagios.lock");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(getenv("REQUEST_METHOD")) {
|
||||||
|
process_cgivars();
|
||||||
|
document_header();
|
||||||
|
}
|
||||||
|
else { /* get arguments */
|
||||||
|
while((c = getopt(argc, argv, "+c:w:s:l:")) != EOF) {
|
||||||
|
switch(c) {
|
||||||
|
case 'c':
|
||||||
|
ct = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
wt = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
status_file = optarg;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
lock_file = optarg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find status file, get lastmod time */
|
||||||
|
if(stat(status_file, &statbuf) == -1) {
|
||||||
|
printf("NAGIOS CRITICAL - could not find status log: %s\n", status_file);
|
||||||
|
exit(STATE_CRITICAL);
|
||||||
|
}
|
||||||
|
time(¤t_time);
|
||||||
|
age = (int)(current_time - statbuf.st_mtime);
|
||||||
|
|
||||||
|
/* find lock file. get pid if it exists */
|
||||||
|
if(stat(lock_file, &statbuf) == -1) {
|
||||||
|
printf("NAGIOS CRITICAL - could not find lock file: %s\n", lock_file);
|
||||||
|
exit(STATE_CRITICAL);
|
||||||
|
}
|
||||||
|
fp = fopen(lock_file, "r");
|
||||||
|
fscanf(fp, "%d", &pid);
|
||||||
|
fclose(fp);
|
||||||
|
proc_file = ssprintf(proc_file, "/proc/%d", pid);
|
||||||
|
|
||||||
|
if(stat("/proc", &statbuf) == 0) {
|
||||||
|
if(stat(proc_file, &statbuf) == -1) {
|
||||||
|
printf("NAGIOS CRITICAL - could not find proc file: %s\n", proc_file);
|
||||||
|
exit(STATE_CRITICAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(snprintf(proc_file, CHARLEN - 1, "/bin/ps -o pid -p %d", pid) &&
|
||||||
|
(fp = popen(proc_file, "r")) != NULL) {
|
||||||
|
fgets(input_buffer, CHARLEN - 1, fp);
|
||||||
|
fgets(input_buffer, CHARLEN - 1, fp);
|
||||||
|
if(sscanf(input_buffer, "%d", &testpid) == 1) {
|
||||||
|
if(testpid != pid) {
|
||||||
|
printf("NAGIOS CRITICAL - could not find process(1): %d\n", pid);
|
||||||
|
exit(STATE_CRITICAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(snprintf(proc_file, CHARLEN - 1, "/bin/ps -eo pid") &&
|
||||||
|
(fp = popen(proc_file, "r")) != NULL) {
|
||||||
|
found = FALSE;
|
||||||
|
fgets(input_buffer, CHARLEN - 1, fp);
|
||||||
|
while(fgets(input_buffer, CHARLEN - 1, fp)) {
|
||||||
|
if(sscanf(input_buffer, "%d", &testpid) == 1)
|
||||||
|
if(testpid == pid) found = TRUE;
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
printf("NAGIOS CRITICAL - could not find process(2): %d\n", pid);
|
||||||
|
exit(STATE_CRITICAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(snprintf(proc_file, CHARLEN - 1, "/bin/ps -Ao pid") &&
|
||||||
|
(fp = popen(proc_file, "r")) != NULL) {
|
||||||
|
found = FALSE;
|
||||||
|
fgets(input_buffer, CHARLEN - 1, fp);
|
||||||
|
while(fgets(input_buffer, CHARLEN - 1, fp)) {
|
||||||
|
if(sscanf(input_buffer, "%d", &testpid) == 1)
|
||||||
|
if(testpid == pid) found = TRUE;
|
||||||
|
}
|
||||||
|
if(!found) {
|
||||||
|
printf("NAGIOS CRITICAL - could not find process(2): %d\n", pid);
|
||||||
|
exit(STATE_CRITICAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ct > 0 && ct < age) {
|
||||||
|
printf("NAGIOS CRITICAL - status written %d seconds ago\n", age);
|
||||||
|
exit(STATE_CRITICAL);
|
||||||
|
}
|
||||||
|
else if(wt > 0 && wt < age) {
|
||||||
|
printf("NAGIOS WARNING - status written %d seconds ago\n", age);
|
||||||
|
exit(STATE_WARNING);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("NAGIOS ok - status written %d seconds ago\n", age);
|
||||||
|
exit(STATE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void document_header(void) {
|
||||||
|
char date_time[48];
|
||||||
|
time_t current_time;
|
||||||
|
|
||||||
|
printf("Cache-Control: no-store\nPragma: no-cache\n");
|
||||||
|
|
||||||
|
time(¤t_time);
|
||||||
|
get_expire_time_string(¤t_time, date_time, (int)sizeof(date_time));
|
||||||
|
printf("Last-Modified: %s\n", date_time);
|
||||||
|
printf("Expires: %s\n", date_time);
|
||||||
|
|
||||||
|
printf("Content-type: text/html\n\n");
|
||||||
|
|
||||||
|
printf("<html>\n<head>\n<title>Nagios Daemon Status</title>\n</head>\n");
|
||||||
|
printf("<body onunload=\"if (window.wnd && wnd.close) wnd.close(); return true;\">\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_cgivars(void) {
|
||||||
|
char **variables;
|
||||||
|
int error = FALSE;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
variables = getcgivars();
|
||||||
|
|
||||||
|
for(x = 0; variables[x] != NULL; x++) {
|
||||||
|
|
||||||
|
/* do some basic length checking on the variable identifier to prevent buffer overflows */
|
||||||
|
if(strlen(variables[x]) >= MAX_INPUT_BUFFER - 1) {
|
||||||
|
x++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get date/time string used in META tags for page expiration */
|
||||||
|
static void get_expire_time_string(time_t *raw_time, char *buffer, int buffer_length) {
|
||||||
|
time_t t;
|
||||||
|
struct tm *tm_ptr;
|
||||||
|
int day;
|
||||||
|
int hour;
|
||||||
|
int minute;
|
||||||
|
int second;
|
||||||
|
int year;
|
||||||
|
char *weekdays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||||
|
char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"};
|
||||||
|
|
||||||
|
if(raw_time == NULL)
|
||||||
|
time(&t);
|
||||||
|
else
|
||||||
|
t = *raw_time;
|
||||||
|
|
||||||
|
tm_ptr = gmtime(&t);
|
||||||
|
|
||||||
|
hour = tm_ptr->tm_hour;
|
||||||
|
minute = tm_ptr->tm_min;
|
||||||
|
second = tm_ptr->tm_sec;
|
||||||
|
day = tm_ptr->tm_mday;
|
||||||
|
year = tm_ptr->tm_year + 1900;
|
||||||
|
|
||||||
|
snprintf(buffer, buffer_length, "%s, %d %s %d %02d:%02d:%02d GMT", weekdays[tm_ptr->tm_wday], day, months[tm_ptr->tm_mon], year, hour, minute, second);
|
||||||
|
buffer[buffer_length - 1] = '\x0';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *strscpy(char *dest, const char *src) {
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(src != NULL)
|
||||||
|
len = strlen(src) + 1;
|
||||||
|
else
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
if(dest == NULL || strlen(dest) < len)
|
||||||
|
dest = realloc(dest, len);
|
||||||
|
if(dest == NULL)
|
||||||
|
terminate(STATE_UNKNOWN, "failed realloc in strscpy\n");
|
||||||
|
|
||||||
|
strncpy(dest, src, len);
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *ssprintf(char *str, const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
int nchars;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
if(str == NULL)
|
||||||
|
str = malloc(CHARLEN);
|
||||||
|
if(str == NULL)
|
||||||
|
terminate(STATE_UNKNOWN, "malloc failed in ssprintf");
|
||||||
|
|
||||||
|
size = max(strlen(str), CHARLEN);
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
nchars = vsnprintf(str, size, fmt, ap);
|
||||||
|
|
||||||
|
if(nchars > -1)
|
||||||
|
if(nchars < size) {
|
||||||
|
va_end(ap);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
size = nchars + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
size *= 2;
|
||||||
|
|
||||||
|
str = realloc(str, nchars + 1);
|
||||||
|
|
||||||
|
if(str == NULL)
|
||||||
|
terminate(STATE_UNKNOWN, "realloc failed in ssprintf");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void terminate(int result, const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
exit(result);
|
||||||
|
}
|
26
contrib/epn_nagios.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/******** BEGIN EMBEDDED PERL INTERPRETER DECLARATIONS ********/
|
||||||
|
|
||||||
|
#include <EXTERN.h>
|
||||||
|
#include <perl.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#undef ctime /* don't need perl's threaded version */
|
||||||
|
#undef printf /* can't use perl's printf until initialized */
|
||||||
|
|
||||||
|
/* In perl.h (or friends) there is a macro that defines sighandler as Perl_sighandler, so we must #undef it so we can use our sighandler() function */
|
||||||
|
#undef sighandler
|
||||||
|
|
||||||
|
|
||||||
|
/* and we don't need perl's reentrant versions */
|
||||||
|
#undef localtime
|
||||||
|
#undef getpwnam
|
||||||
|
#undef getgrnam
|
||||||
|
#undef strerror
|
||||||
|
|
||||||
|
#ifdef aTHX
|
||||||
|
EXTERN_C void xs_init(pTHX);
|
||||||
|
#else
|
||||||
|
EXTERN_C void xs_init(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******** END EMBEDDED PERL INTERPRETER DECLARATIONS ********/
|
26
contrib/eventhandlers/disable_active_service_checks
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Write a command to the Nagios command file to cause
|
||||||
|
# it to disable active service checks. This can be
|
||||||
|
# referred to as 'standby' mode in a redundant monitoring
|
||||||
|
# environment.
|
||||||
|
|
||||||
|
# Notes:
|
||||||
|
# 1) This script is not intended to be used as an
|
||||||
|
# event handler by itself. Instead, it is used by other
|
||||||
|
# event handler scripts (like the redundancy examples).
|
||||||
|
# 2) In order for Nagios to process any commands that
|
||||||
|
# are written to the command file, you must enable
|
||||||
|
# the check_external_commands option in the main
|
||||||
|
# configuration file.
|
||||||
|
|
||||||
|
printfcmd="/usr/bin/printf"
|
||||||
|
|
||||||
|
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
|
||||||
|
|
||||||
|
# get the current date/time in seconds since UNIX epoch
|
||||||
|
datetime=`date +%s`
|
||||||
|
|
||||||
|
# pipe the command to the command file
|
||||||
|
`$printfcmd "[%i] STOP_EXECUTING_SVC_CHECKS\n" $datetime >> $CommandFile`
|
||||||
|
|
24
contrib/eventhandlers/disable_notifications
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Write a command to the Nagios command file to cause
|
||||||
|
# it to disable host and service notifications
|
||||||
|
|
||||||
|
# Notes:
|
||||||
|
# 1) This script is not intended to be used as an
|
||||||
|
# event handler by itself. Instead, it is used by other
|
||||||
|
# event handler scripts (like the redundancy examples).
|
||||||
|
# 2) In order for Nagios to process any commands that
|
||||||
|
# are written to the command file, you must enable
|
||||||
|
# the check_external_commands option in the main
|
||||||
|
# configuration file.
|
||||||
|
|
||||||
|
printfcmd="/usr/bin/printf"
|
||||||
|
|
||||||
|
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
|
||||||
|
|
||||||
|
# get the current date/time in seconds since UNIX epoch
|
||||||
|
datetime=`date +%s`
|
||||||
|
|
||||||
|
# pipe the command to the command file
|
||||||
|
`$printfcmd "[%i] DISABLE_NOTIFICATIONS;%i\n" $datetime $datetime >> $CommandFile`
|
||||||
|
|
46
contrib/eventhandlers/distributed-monitoring/obsessive_svc_handler
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# OBSESSIVE_SVC_HANDLER
|
||||||
|
# Written by Ethan Galstad (nagios@nagils.org)
|
||||||
|
# Last Modified: 07-19-2001
|
||||||
|
#
|
||||||
|
# This script is intended to run as the OCSP command
|
||||||
|
# on a distributed monitoring server. The script calls
|
||||||
|
# submit_check_result_via_nsca to send the service check
|
||||||
|
# results to the central monitoring server.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# $1 = host_name (Short name of host that the service is
|
||||||
|
# associated with)
|
||||||
|
# $2 = svc_description (Description of the service)
|
||||||
|
# $3 = state_string (A string representing the status of
|
||||||
|
# the given service - "OK", "WARNING", "CRITICAL"
|
||||||
|
# or "UNKNOWN")
|
||||||
|
# $4 = plugin_output (A text string that should be used
|
||||||
|
# as the plugin output for the service checks)
|
||||||
|
#
|
||||||
|
|
||||||
|
# Location of the submit_check_result_via_nsca script
|
||||||
|
SubmitCmd="/usr/local/nagios/libexec/eventhandlers/submit_check_result_via_nsca"
|
||||||
|
|
||||||
|
# Convert the state string to the corresponding return code
|
||||||
|
return_code=-1
|
||||||
|
|
||||||
|
case "$3" in
|
||||||
|
OK)
|
||||||
|
return_code=0
|
||||||
|
;;
|
||||||
|
WARNING)
|
||||||
|
return_code=1
|
||||||
|
;;
|
||||||
|
CRITICAL)
|
||||||
|
return_code=2
|
||||||
|
;;
|
||||||
|
UNKNOWN)
|
||||||
|
return_code=3
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Send the service check results to the central monitoring server
|
||||||
|
$SubmitCmd "$1" "$2" $return_code "$4"
|
||||||
|
|
39
contrib/eventhandlers/distributed-monitoring/submit_check_result_via_nsca
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# SUBMIT_CHECK_RESULT_VIA_NSCA
|
||||||
|
# Written by Ethan Galstad (egalstad@nagios.org)
|
||||||
|
# Last Modified: 10-15-2008
|
||||||
|
#
|
||||||
|
# This script will send passive check results to the
|
||||||
|
# nsca daemon that runs on the central Nagios server.
|
||||||
|
# If you simply want to submit passive checks from the
|
||||||
|
# same machine that Nagios is running on, look at the
|
||||||
|
# submit_check_result script.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# $1 = host_name (Short name of host that the service is
|
||||||
|
# associated with)
|
||||||
|
# $2 = svc_description (Description of the service)
|
||||||
|
# $3 = return_code (An integer that determines the state
|
||||||
|
# of the service check, 0=OK, 1=WARNING, 2=CRITICAL,
|
||||||
|
# 3=UNKNOWN).
|
||||||
|
# $4 = plugin_output (A text string that should be used
|
||||||
|
# as the plugin output for the service check)s
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
# Modify the NagiosHost parameter to match the name or
|
||||||
|
# IP address of the central server that has the nsca
|
||||||
|
# daemon running.
|
||||||
|
|
||||||
|
printfcmd="/usr/bin/printf"
|
||||||
|
|
||||||
|
NscaBin="/usr/local/nagios/libexec/send_nsca"
|
||||||
|
NscaCfg="/usr/local/nagios/etc/send_nsca.cfg"
|
||||||
|
NagiosHost="nagioshost"
|
||||||
|
|
||||||
|
# Fire the data off to the NSCA daemon using the send_nsca script
|
||||||
|
$printfcmd "%s\t%s\t%s\t%s\n" "$1" "$2" "$3" "$4" | $NscaBin -H $NagiosHost -c $NscaCfg
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|
26
contrib/eventhandlers/enable_active_service_checks
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Write a command to the Nagios command file to cause
|
||||||
|
# it to enable active service checks. This can be
|
||||||
|
# referred to as 'active' mode in a redundant monitoring
|
||||||
|
# environment.
|
||||||
|
|
||||||
|
# Notes:
|
||||||
|
# 1) This script is not intended to be used as an
|
||||||
|
# event handler by itself. Instead, it is used by other
|
||||||
|
# event handler scripts (like the redundancy examples).
|
||||||
|
# 2) In order for Nagios to process any commands that
|
||||||
|
# are written to the command file, you must enable
|
||||||
|
# the check_external_commands option in the main
|
||||||
|
# configuration file.
|
||||||
|
|
||||||
|
printfcmd="/usr/bin/printf"
|
||||||
|
|
||||||
|
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
|
||||||
|
|
||||||
|
# get the current date/time in seconds since UNIX epoch
|
||||||
|
datetime=`date +%s`
|
||||||
|
|
||||||
|
# pipe the command to the command file
|
||||||
|
`$printfcmd "[%i] START_EXECUTING_SVC_CHECKS\n" $datetime >> $CommandFile`
|
||||||
|
|
27
contrib/eventhandlers/enable_notifications
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Write a command to the Nagios command file to cause
|
||||||
|
# it to enable host and service notifications
|
||||||
|
|
||||||
|
# Notes:
|
||||||
|
# 1) This script is not intended to be used as an
|
||||||
|
# event handler by itself. Instead, it is used by other
|
||||||
|
# event handler scripts (like the redundancy examples).
|
||||||
|
# 2) In order for Nagios to process any commands that
|
||||||
|
# are written to the command file, you must enable
|
||||||
|
# the check_external_commands option in the main
|
||||||
|
# configuration file.
|
||||||
|
|
||||||
|
printfcmd="/usr/bin/printf"
|
||||||
|
|
||||||
|
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
|
||||||
|
|
||||||
|
# get the current date/time in seconds since UNIX epoch
|
||||||
|
datetime=`date +%s`
|
||||||
|
|
||||||
|
# pipe the command to the command file
|
||||||
|
`$printfcmd "[%i] ENABLE_NOTIFICATIONS;%i\n" $datetime $datetime >> $CommandFile`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
68
contrib/eventhandlers/redundancy-scenario1/handle-master-host-event
Executable file
@ -0,0 +1,68 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# REDUNDANCY EVENT HANDLER SCRIPT
|
||||||
|
# Written By: Ethan Galstad (egalstad@nagios.org)
|
||||||
|
# Last Modified: 02-19-2004
|
||||||
|
#
|
||||||
|
# This is an example script for implementing redundancy.
|
||||||
|
# Read the HTML documentation on redundant monitoring for more
|
||||||
|
# information on what this does.
|
||||||
|
|
||||||
|
# Location of the echo and mail commands
|
||||||
|
echocmd="/bin/echo"
|
||||||
|
mailcmd="/bin/mail"
|
||||||
|
|
||||||
|
# Location of the event handlers
|
||||||
|
eventhandlerdir="/usr/local/nagios/libexec/eventhandlers"
|
||||||
|
|
||||||
|
|
||||||
|
# Only take action on hard host states...
|
||||||
|
case "$2" in
|
||||||
|
HARD)
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
DOWN)
|
||||||
|
# The master host has gone down!
|
||||||
|
# We should now become the master host and take
|
||||||
|
# over the responsibilities of monitoring the
|
||||||
|
# network, so enable notifications...
|
||||||
|
|
||||||
|
`$eventhandlerdir/enable_notifications`
|
||||||
|
|
||||||
|
|
||||||
|
# Notify someone of what has happened with the original
|
||||||
|
# master server and our taking over the monitoring
|
||||||
|
# responsibilities. No one was notified of the master
|
||||||
|
# host going down, since the notification would have
|
||||||
|
# occurred while we were in standby mode, so this is a good idea...
|
||||||
|
|
||||||
|
#`$echocmd "Master Nagios host is down!" | /bin/mail -s "Master Nagios Host Is Down" root@localhost`
|
||||||
|
#`$echocmd "Slave Nagios host has entered ACTIVE mode and taken over network monitoring responsibilities!" | $mailcmd -s "Slave Nagios Host Has Entered ACTIVE Mode" root@localhost`
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
UP)
|
||||||
|
# The master host has recovered!
|
||||||
|
# We should go back to being the slave host and
|
||||||
|
# let the master host do the monitoring, so
|
||||||
|
# disable notifications...
|
||||||
|
|
||||||
|
`$eventhandlerdir/disable_notifications`
|
||||||
|
|
||||||
|
|
||||||
|
# Notify someone of what has happened. Users were
|
||||||
|
# already notified of the master host recovery because we
|
||||||
|
# were in active mode at the time the recovery happened.
|
||||||
|
# However, we should let someone know that we're switching
|
||||||
|
# back to standby mode...
|
||||||
|
|
||||||
|
#`$echocmd "The master Nagios host has recovered, so the slave Nagios host has returned to standby mode..." | $mailcmd -s "Slave Nagios Host Has Returned To STANDBY Mode" root@localhost`
|
||||||
|
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
exit 0
|
||||||
|
|
58
contrib/eventhandlers/redundancy-scenario1/handle-master-proc-event
Executable file
@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# REDUNDANCY EVENT HANDLER SCRIPT
|
||||||
|
# Written By: Ethan Galstad (egalstad@nagios.org)
|
||||||
|
# Last Modified: 05-30-2006
|
||||||
|
#
|
||||||
|
# This is an example script for implementing redundancy.
|
||||||
|
# Read the HTML documentation on redundant monitoring for more
|
||||||
|
# information on what this does.
|
||||||
|
|
||||||
|
# Location of the echo and mail commands
|
||||||
|
echocmd="/bin/echo"
|
||||||
|
mailcmd="/bin/mail"
|
||||||
|
|
||||||
|
# Location of the event handlers
|
||||||
|
eventhandlerdir="/usr/local/nagios/libexec/eventhandlers"
|
||||||
|
|
||||||
|
|
||||||
|
# Only take action on hard service states...
|
||||||
|
case "$2" in
|
||||||
|
HARD)
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
CRITICAL)
|
||||||
|
|
||||||
|
# The master Nagios process is not running!
|
||||||
|
# We should now become the master host and
|
||||||
|
# take over the responsibility of monitoring
|
||||||
|
# the network, so enable active checks...
|
||||||
|
|
||||||
|
`$eventhandlerdir/enable_active_service_checks`
|
||||||
|
;;
|
||||||
|
|
||||||
|
WARNING|UNKNOWN)
|
||||||
|
|
||||||
|
# The master Nagios process may or may not
|
||||||
|
# be running.. We won't do anything here, but
|
||||||
|
# to be on the safe side you may decide you
|
||||||
|
# want the slave host to become the master in
|
||||||
|
# these situations...
|
||||||
|
;;
|
||||||
|
|
||||||
|
OK)
|
||||||
|
|
||||||
|
# The master Nagios process running again!
|
||||||
|
# We should go back to being the slave host,
|
||||||
|
# so disable active checks
|
||||||
|
|
||||||
|
`eventhandlerdir/disable_active_service_checks`
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
|
36
contrib/eventhandlers/submit_check_result
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# SUBMIT_CHECK_RESULT
|
||||||
|
# Written by Ethan Galstad (egalstad@nagios.org)
|
||||||
|
# Last Modified: 02-18-2002
|
||||||
|
#
|
||||||
|
# This script will write a command to the Nagios command
|
||||||
|
# file to cause Nagios to process a passive service check
|
||||||
|
# result. Note: This script is intended to be run on the
|
||||||
|
# same host that is running Nagios. If you want to
|
||||||
|
# submit passive check results from a remote machine, look
|
||||||
|
# at using the nsca addon.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# $1 = host_name (Short name of host that the service is
|
||||||
|
# associated with)
|
||||||
|
# $2 = svc_description (Description of the service)
|
||||||
|
# $3 = return_code (An integer that determines the state
|
||||||
|
# of the service check, 0=OK, 1=WARNING, 2=CRITICAL,
|
||||||
|
# 3=UNKNOWN).
|
||||||
|
# $4 = plugin_output (A text string that should be used
|
||||||
|
# as the plugin output for the service check)
|
||||||
|
#
|
||||||
|
|
||||||
|
echocmd="/bin/echo"
|
||||||
|
|
||||||
|
CommandFile="/usr/local/nagios/var/rw/nagios.cmd"
|
||||||
|
|
||||||
|
# get the current date/time in seconds since UNIX epoch
|
||||||
|
datetime=`date +%s`
|
||||||
|
|
||||||
|
# create the command line to add to the command file
|
||||||
|
cmdline="[$datetime] PROCESS_SERVICE_CHECK_RESULT;$1;$2;$3;$4"
|
||||||
|
|
||||||
|
# append the command to the end of the command file
|
||||||
|
`$echocmd $cmdline >> $CommandFile`
|
BIN
contrib/exfoliation/images/NagiosEnterprises-whitebg-112x46.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
contrib/exfoliation/images/ack.gif
Normal file
After Width: | Height: | Size: 856 B |
BIN
contrib/exfoliation/images/action-graph.gif
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
contrib/exfoliation/images/action-nagios.gif
Normal file
After Width: | Height: | Size: 171 B |
BIN
contrib/exfoliation/images/action-orig.gif
Normal file
After Width: | Height: | Size: 162 B |
BIN
contrib/exfoliation/images/action.gif
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
contrib/exfoliation/images/command.png
Normal file
After Width: | Height: | Size: 394 B |
BIN
contrib/exfoliation/images/comment.gif
Normal file
After Width: | Height: | Size: 909 B |
BIN
contrib/exfoliation/images/contexthelp1.gif
Normal file
After Width: | Height: | Size: 253 B |
BIN
contrib/exfoliation/images/contexthelp2.gif
Normal file
After Width: | Height: | Size: 253 B |
BIN
contrib/exfoliation/images/critical.png
Normal file
After Width: | Height: | Size: 382 B |
BIN
contrib/exfoliation/images/delay.gif
Normal file
After Width: | Height: | Size: 935 B |
BIN
contrib/exfoliation/images/delete.gif
Normal file
After Width: | Height: | Size: 961 B |
BIN
contrib/exfoliation/images/detail.gif
Normal file
After Width: | Height: | Size: 138 B |
BIN
contrib/exfoliation/images/disabled.gif
Normal file
After Width: | Height: | Size: 100 B |
BIN
contrib/exfoliation/images/down.gif
Normal file
After Width: | Height: | Size: 856 B |
BIN
contrib/exfoliation/images/downtime.gif
Normal file
After Width: | Height: | Size: 933 B |
BIN
contrib/exfoliation/images/empty.gif
Normal file
After Width: | Height: | Size: 807 B |
BIN
contrib/exfoliation/images/enabled.gif
Normal file
After Width: | Height: | Size: 90 B |
BIN
contrib/exfoliation/images/extinfo.gif
Normal file
After Width: | Height: | Size: 911 B |
BIN
contrib/exfoliation/images/favicon.ico
Normal file
After Width: | Height: | Size: 822 B |